aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World')
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs20
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs26
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs358
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs76
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RestartModule.cs115
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs148
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs577
13 files changed, 898 insertions, 479 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 32d245f..fcfdf7c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -490,6 +490,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver
490 // being no copy/no mod for everyone 490 // being no copy/no mod for everyone
491 lock (part.TaskInventory) 491 lock (part.TaskInventory)
492 { 492 {
493 if (!ResolveUserUuid(scene, part.CreatorID))
494 part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
495
496 if (!ResolveUserUuid(scene, part.OwnerID))
497 part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
498
499 if (!ResolveUserUuid(scene, part.LastOwnerID))
500 part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
501
502 // And zap any troublesome sit target information
503 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
504 part.SitTargetPosition = new Vector3(0, 0, 0);
505
506 // Fix ownership/creator of inventory items
507 // Not doing so results in inventory items
508 // being no copy/no mod for everyone
509 part.TaskInventory.LockItemsForRead(true);
493 TaskInventoryDictionary inv = part.TaskInventory; 510 TaskInventoryDictionary inv = part.TaskInventory;
494 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) 511 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
495 { 512 {
@@ -510,6 +527,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
510 if (!ResolveGroupUuid(kvp.Value.GroupID)) 527 if (!ResolveGroupUuid(kvp.Value.GroupID))
511 kvp.Value.GroupID = UUID.Zero; 528 kvp.Value.GroupID = UUID.Zero;
512 } 529 }
530 part.TaskInventory.LockItemsForRead(false);
513 } 531 }
514 } 532 }
515 533
@@ -899,4 +917,4 @@ namespace OpenSim.Region.CoreModules.World.Archiver
899 return dearchivedScenes; 917 return dearchivedScenes;
900 } 918 }
901 } 919 }
902} \ No newline at end of file 920}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 9600023..ada7ecc 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -271,18 +271,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
271 271
272 if (asset != null) 272 if (asset != null)
273 { 273 {
274 if (m_options.ContainsKey("verbose")) 274// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
275 m_log.InfoFormat("[ARCHIVER]: Writing asset {0}", id);
276
277 m_foundAssetUuids.Add(asset.FullID); 275 m_foundAssetUuids.Add(asset.FullID);
278 276
279 m_assetsArchiver.WriteAsset(PostProcess(asset)); 277 m_assetsArchiver.WriteAsset(PostProcess(asset));
280 } 278 }
281 else 279 else
282 { 280 {
283 if (m_options.ContainsKey("verbose")) 281// m_log.DebugFormat("[ARCHIVER]: Recording asset {0} as not found", id);
284 m_log.InfoFormat("[ARCHIVER]: Recording asset {0} as not found", id);
285
286 m_notFoundAssetUuids.Add(new UUID(id)); 282 m_notFoundAssetUuids.Add(new UUID(id));
287 } 283 }
288 284
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 91f6501..a5f5749 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -331,6 +331,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
331 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>(); 331 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>();
332 if (restartModule != null) 332 if (restartModule != null)
333 { 333 {
334 if (timeInSeconds == -1)
335 {
336 m_delayCount++;
337 if (m_delayCount > 3)
338 return;
339
340 restartModule.DelayRestart(3600, "Restart delayed by region manager");
341 return;
342 }
343
334 List<int> times = new List<int>(); 344 List<int> times = new List<int>();
335 while (timeInSeconds > 0) 345 while (timeInSeconds > 0)
336 { 346 {
@@ -1245,8 +1255,14 @@ namespace OpenSim.Region.CoreModules.World.Estate
1245 flags |= RegionFlags.NoFly; 1255 flags |= RegionFlags.NoFly;
1246 if (Scene.RegionInfo.RegionSettings.RestrictPushing) 1256 if (Scene.RegionInfo.RegionSettings.RestrictPushing)
1247 flags |= RegionFlags.RestrictPushObject; 1257 flags |= RegionFlags.RestrictPushObject;
1258 if (Scene.RegionInfo.RegionSettings.AllowLandJoinDivide)
1259 flags |= RegionFlags.AllowParcelChanges;
1248 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch) 1260 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch)
1249 flags |= RegionFlags.BlockParcelSearch; 1261 flags |= RegionFlags.BlockParcelSearch;
1262 if (Scene.RegionInfo.RegionSettings.GodBlockSearch)
1263 flags |= (RegionFlags)(1 << 11);
1264 if (Scene.RegionInfo.RegionSettings.Casino)
1265 flags |= (RegionFlags)(1 << 10);
1250 1266
1251 if (Scene.RegionInfo.RegionSettings.FixedSun) 1267 if (Scene.RegionInfo.RegionSettings.FixedSun)
1252 flags |= RegionFlags.SunFixed; 1268 flags |= RegionFlags.SunFixed;
@@ -1254,6 +1270,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
1254 flags |= RegionFlags.Sandbox; 1270 flags |= RegionFlags.Sandbox;
1255 if (Scene.RegionInfo.EstateSettings.AllowVoice) 1271 if (Scene.RegionInfo.EstateSettings.AllowVoice)
1256 flags |= RegionFlags.AllowVoice; 1272 flags |= RegionFlags.AllowVoice;
1273 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1274 flags |= RegionFlags.AllowLandmark;
1275 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1276 flags |= RegionFlags.AllowSetHome;
1257 if (Scene.RegionInfo.EstateSettings.BlockDwell) 1277 if (Scene.RegionInfo.EstateSettings.BlockDwell)
1258 flags |= RegionFlags.BlockDwell; 1278 flags |= RegionFlags.BlockDwell;
1259 if (Scene.RegionInfo.EstateSettings.ResetHomeOnTeleport) 1279 if (Scene.RegionInfo.EstateSettings.ResetHomeOnTeleport)
@@ -1299,6 +1319,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
1299 flags |= RegionFlags.ResetHomeOnTeleport; 1319 flags |= RegionFlags.ResetHomeOnTeleport;
1300 if (Scene.RegionInfo.EstateSettings.TaxFree) 1320 if (Scene.RegionInfo.EstateSettings.TaxFree)
1301 flags |= RegionFlags.TaxFree; 1321 flags |= RegionFlags.TaxFree;
1322 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1323 flags |= RegionFlags.AllowLandmark;
1324 if (Scene.RegionInfo.EstateSettings.AllowParcelChanges)
1325 flags |= RegionFlags.AllowParcelChanges;
1326 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1327 flags |= RegionFlags.AllowSetHome;
1302 if (Scene.RegionInfo.EstateSettings.DenyMinors) 1328 if (Scene.RegionInfo.EstateSettings.DenyMinors)
1303 flags |= (RegionFlags)(1 << 30); 1329 flags |= (RegionFlags)(1 << 30);
1304 1330
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 693de1d..b4f7d51 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -88,19 +88,21 @@ namespace OpenSim.Region.CoreModules.World.Land
88 /// <value> 88 /// <value>
89 /// Land objects keyed by local id 89 /// Land objects keyed by local id
90 /// </value> 90 /// </value>
91 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); 91// private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
92
93 //ubit: removed the readonly so i can move it around
94 private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
92 95
93 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 96 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
94 97
95 private bool m_allowedForcefulBans = true; 98 private bool m_allowedForcefulBans = true;
99 private UUID DefaultGodParcelGroup;
100 private string DefaultGodParcelName;
96 101
97 // caches ExtendedLandData 102 // caches ExtendedLandData
98 private Cache parcelInfoCache; 103 private Cache parcelInfoCache;
99 104 private Dictionary<UUID, Vector3> forcedPosition =
100 /// <summary> 105 new Dictionary<UUID, Vector3>();
101 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
102 /// </summary>
103 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>();
104 106
105 #region INonSharedRegionModule Members 107 #region INonSharedRegionModule Members
106 108
@@ -111,6 +113,12 @@ namespace OpenSim.Region.CoreModules.World.Land
111 113
112 public void Initialise(IConfigSource source) 114 public void Initialise(IConfigSource source)
113 { 115 {
116 IConfig cnf = source.Configs["LandManagement"];
117 if (cnf != null)
118 {
119 DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
120 DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel");
121 }
114 } 122 }
115 123
116 public void AddRegion(Scene scene) 124 public void AddRegion(Scene scene)
@@ -163,13 +171,6 @@ namespace OpenSim.Region.CoreModules.World.Land
163 m_scene.UnregisterModuleCommander(m_commander.Name); 171 m_scene.UnregisterModuleCommander(m_commander.Name);
164 } 172 }
165 173
166// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
167// {
168// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
169// reason = "You are not allowed to enter this sim.";
170// return nearestParcel != null;
171// }
172
173 /// <summary> 174 /// <summary>
174 /// Processes commandline input. Do not call directly. 175 /// Processes commandline input. Do not call directly.
175 /// </summary> 176 /// </summary>
@@ -213,7 +214,6 @@ namespace OpenSim.Region.CoreModules.World.Land
213 client.OnParcelEjectUser += ClientOnParcelEjectUser; 214 client.OnParcelEjectUser += ClientOnParcelEjectUser;
214 client.OnParcelFreezeUser += ClientOnParcelFreezeUser; 215 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
215 216
216
217 EntityBase presenceEntity; 217 EntityBase presenceEntity;
218 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 218 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
219 { 219 {
@@ -229,48 +229,6 @@ namespace OpenSim.Region.CoreModules.World.Land
229 229
230 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 230 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
231 { 231 {
232 //If we are forcing a position for them to go
233 if (forcedPosition.ContainsKey(remoteClient.AgentId))
234 {
235 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
236
237 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
238 //When the avatar walks into a ban line on the ground, it prevents getting stuck
239 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
240
241 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
242 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
243 {
244// m_log.DebugFormat(
245// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
246// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
247
248 forcedPosition.Remove(remoteClient.AgentId);
249 }
250 //if we are far away, teleport
251 else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
252 {
253 Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
254// m_log.DebugFormat(
255// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
256// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
257
258 m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
259 forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
260
261 forcedPosition.Remove(remoteClient.AgentId);
262 }
263 else
264 {
265// m_log.DebugFormat(
266// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
267// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
268
269 //Forces them toward the forced position we want if they aren't there yet
270 agentData.UseClientAgentPosition = true;
271 agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
272 }
273 }
274 } 232 }
275 233
276 public void Close() 234 public void Close()
@@ -295,6 +253,7 @@ namespace OpenSim.Region.CoreModules.World.Land
295 { 253 {
296 LandData newData = data.Copy(); 254 LandData newData = data.Copy();
297 newData.LocalID = local_id; 255 newData.LocalID = local_id;
256 ILandObject landobj = null;
298 257
299 ILandObject land; 258 ILandObject land;
300 lock (m_landList) 259 lock (m_landList)
@@ -334,14 +293,14 @@ namespace OpenSim.Region.CoreModules.World.Land
334 protected ILandObject CreateDefaultParcel() 293 protected ILandObject CreateDefaultParcel()
335 { 294 {
336 m_log.DebugFormat( 295 m_log.DebugFormat(
337 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 296 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
338 297
339 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 298 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
340 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 299 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
341 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 300 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
342 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 301 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
343 302
344 return AddLandObject(fullSimParcel); 303 return AddLandObject(fullSimParcel);
345 } 304 }
346 305
347 public List<ILandObject> AllParcels() 306 public List<ILandObject> AllParcels()
@@ -390,10 +349,16 @@ namespace OpenSim.Region.CoreModules.World.Land
390 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 349 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
391 { 350 {
392 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 351 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
393 if (position.HasValue) 352
394 { 353 if (!position.HasValue)
395 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; 354 return;
396 } 355
356 bool isFlying = avatar.PhysicsActor.Flying;
357 avatar.RemoveFromPhysicalScene();
358
359 avatar.AbsolutePosition = (Vector3)position;
360
361 avatar.AddToPhysicalScene(isFlying);
397 } 362 }
398 363
399 public void SendYouAreRestrictedNotice(ScenePresence avatar) 364 public void SendYouAreRestrictedNotice(ScenePresence avatar)
@@ -413,29 +378,7 @@ namespace OpenSim.Region.CoreModules.World.Land
413 } 378 }
414 379
415 if (parcelAvatarIsEntering != null) 380 if (parcelAvatarIsEntering != null)
416 { 381 EnforceBans(parcelAvatarIsEntering, avatar);
417 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
418 {
419 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
420 {
421 SendYouAreBannedNotice(avatar);
422 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
423 }
424 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
425 {
426 SendYouAreRestrictedNotice(avatar);
427 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
428 }
429 else
430 {
431 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
432 }
433 }
434 else
435 {
436 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
437 }
438 }
439 } 382 }
440 } 383 }
441 384
@@ -464,30 +407,51 @@ namespace OpenSim.Region.CoreModules.World.Land
464 407
465 public void SendLandUpdate(ScenePresence avatar, bool force) 408 public void SendLandUpdate(ScenePresence avatar, bool force)
466 { 409 {
410
411 /* stop sendind same data twice
412 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
413 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
414
415 if (over != null)
416 {
417
418 if (force)
419 {
420 if (!avatar.IsChildAgent)
421 {
422 over.SendLandUpdateToClient(avatar.ControllingClient);
423 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
424 m_scene.RegionInfo.RegionID);
425 }
426 }
427
428 if (avatar.currentParcelUUID != over.LandData.GlobalID)
429 {
430 if (!avatar.IsChildAgent)
431 {
432 over.SendLandUpdateToClient(avatar.ControllingClient);
433 avatar.currentParcelUUID = over.LandData.GlobalID;
434 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
435 m_scene.RegionInfo.RegionID);
436 }
437 }
438 */
439 if (avatar.IsChildAgent)
440 return;
441
467 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 442 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
468 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 443 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
469 444
470 if (over != null) 445 if (over != null)
471 { 446 {
472 if (force) 447 bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID);
473 { 448 if (force || NotsameID)
474 if (!avatar.IsChildAgent)
475 {
476 over.SendLandUpdateToClient(avatar.ControllingClient);
477 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
478 m_scene.RegionInfo.RegionID);
479 }
480 }
481
482 if (avatar.currentParcelUUID != over.LandData.GlobalID)
483 { 449 {
484 if (!avatar.IsChildAgent) 450 over.SendLandUpdateToClient(avatar.ControllingClient);
485 { 451 if (NotsameID)
486 over.SendLandUpdateToClient(avatar.ControllingClient);
487 avatar.currentParcelUUID = over.LandData.GlobalID; 452 avatar.currentParcelUUID = over.LandData.GlobalID;
488 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, 453 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
489 m_scene.RegionInfo.RegionID); 454 m_scene.RegionInfo.RegionID);
490 }
491 } 455 }
492 } 456 }
493 } 457 }
@@ -539,6 +503,7 @@ namespace OpenSim.Region.CoreModules.World.Land
539 //when we are finally in a safe place, lets release the forced position lock 503 //when we are finally in a safe place, lets release the forced position lock
540 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 504 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
541 } 505 }
506 EnforceBans(parcel, clientAvatar);
542 } 507 }
543 } 508 }
544 509
@@ -689,27 +654,28 @@ namespace OpenSim.Region.CoreModules.World.Land
689 /// </summary> 654 /// </summary>
690 public void Clear(bool setupDefaultParcel) 655 public void Clear(bool setupDefaultParcel)
691 { 656 {
692 List<ILandObject> parcels; 657 Dictionary<int, ILandObject> landworkList;
658 // move to work pointer since we are deleting it all
693 lock (m_landList) 659 lock (m_landList)
694 { 660 {
695 parcels = new List<ILandObject>(m_landList.Values); 661 landworkList = m_landList;
662 m_landList = new Dictionary<int, ILandObject>();
696 } 663 }
697 664
698 foreach (ILandObject lo in parcels) 665 // this 2 methods have locks (now)
666 ResetSimLandObjects();
667
668 if (setupDefaultParcel)
669 CreateDefaultParcel();
670
671 // fire outside events unlocked
672 foreach (ILandObject lo in landworkList.Values)
699 { 673 {
700 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 674 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
701 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); 675 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
702 } 676 }
677 landworkList.Clear();
703 678
704 lock (m_landList)
705 {
706 m_landList.Clear();
707
708 ResetSimLandObjects();
709 }
710
711 if (setupDefaultParcel)
712 CreateDefaultParcel();
713 } 679 }
714 680
715 private void performFinalLandJoin(ILandObject master, ILandObject slave) 681 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -756,7 +722,7 @@ namespace OpenSim.Region.CoreModules.World.Land
756 int x; 722 int x;
757 int y; 723 int y;
758 724
759 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 725 if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0)
760 return null; 726 return null;
761 727
762 try 728 try
@@ -806,14 +772,13 @@ namespace OpenSim.Region.CoreModules.World.Land
806 { 772 {
807 try 773 try
808 { 774 {
809 return m_landList[m_landIDList[x / 4, y / 4]]; 775 //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4]))
776 return m_landList[m_landIDList[x / 4, y / 4]];
777 //else
778 // return null;
810 } 779 }
811 catch (IndexOutOfRangeException) 780 catch (IndexOutOfRangeException)
812 { 781 {
813// m_log.WarnFormat(
814// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}",
815// x, y, m_scene.RegionInfo.RegionName);
816
817 return null; 782 return null;
818 } 783 }
819 } 784 }
@@ -1097,6 +1062,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1097 //Owner Flag 1062 //Owner Flag
1098 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1063 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1099 } 1064 }
1065 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1066 {
1067 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP);
1068 }
1100 else if (currentParcelBlock.LandData.SalePrice > 0 && 1069 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1101 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || 1070 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1102 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) 1071 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
@@ -1177,8 +1146,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1177 { 1146 {
1178 if (!temp.Contains(currentParcel)) 1147 if (!temp.Contains(currentParcel))
1179 { 1148 {
1180 currentParcel.ForceUpdateLandInfo(); 1149 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId))
1181 temp.Add(currentParcel); 1150 {
1151 currentParcel.ForceUpdateLandInfo();
1152 temp.Add(currentParcel);
1153 }
1182 } 1154 }
1183 } 1155 }
1184 } 1156 }
@@ -1397,8 +1369,26 @@ namespace OpenSim.Region.CoreModules.World.Land
1397 1369
1398 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1370 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1399 { 1371 {
1400// m_log.DebugFormat( 1372 Dictionary<int, ILandObject> landworkList;
1401// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name); 1373 // move to work pointer since we are deleting it all
1374 lock (m_landList)
1375 {
1376 landworkList = m_landList;
1377 m_landList = new Dictionary<int, ILandObject>();
1378 }
1379
1380 //Remove all the land objects in the sim and then process our new data
1381 foreach (int n in landworkList.Keys)
1382 {
1383 m_scene.EventManager.TriggerLandObjectRemoved(landworkList[n].LandData.GlobalID);
1384 }
1385 landworkList.Clear();
1386
1387 lock (m_landList)
1388 {
1389 m_landIDList.Initialize();
1390 m_landList.Clear();
1391 }
1402 1392
1403 for (int i = 0; i < data.Count; i++) 1393 for (int i = 0; i < data.Count; i++)
1404 IncomingLandObjectFromStorage(data[i]); 1394 IncomingLandObjectFromStorage(data[i]);
@@ -1406,10 +1396,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1406 1396
1407 public void IncomingLandObjectFromStorage(LandData data) 1397 public void IncomingLandObjectFromStorage(LandData data)
1408 { 1398 {
1399
1409 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); 1400 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
1410 new_land.LandData = data.Copy(); 1401 new_land.LandData = data.Copy();
1411 new_land.SetLandBitmapFromByteArray(); 1402 new_land.SetLandBitmapFromByteArray();
1412 AddLandObject(new_land); 1403 AddLandObject(new_land);
1404 new_land.SendLandUpdateToAvatarsOverMe();
1413 } 1405 }
1414 1406
1415 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1407 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1740,7 +1732,86 @@ namespace OpenSim.Region.CoreModules.World.Land
1740 1732
1741 UpdateLandObject(localID, land.LandData); 1733 UpdateLandObject(localID, land.LandData);
1742 } 1734 }
1743 1735
1736 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
1737 {
1738 ILandObject land = null;
1739 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
1740 foreach (ILandObject landObject in Land)
1741 {
1742 if (landObject.LandData.LocalID == landID)
1743 {
1744 land = landObject;
1745 }
1746 }
1747 land.DeedToGroup(DefaultGodParcelGroup);
1748 land.LandData.Name = DefaultGodParcelName;
1749 land.SendLandUpdateToAvatarsOverMe();
1750 }
1751
1752 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
1753 {
1754 ScenePresence SP;
1755 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
1756 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
1757 if (SP.UserLevel != 0)
1758 {
1759 if (flags == 0) //All parcels, scripted or not
1760 {
1761 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1762 {
1763 if (e.OwnerID == targetID)
1764 {
1765 returns.Add(e);
1766 }
1767 }
1768 );
1769 }
1770 if (flags == 4) //All parcels, scripted object
1771 {
1772 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1773 {
1774 if (e.OwnerID == targetID)
1775 {
1776 if (e.ContainsScripts())
1777 {
1778 returns.Add(e);
1779 }
1780 }
1781 }
1782 );
1783 }
1784 if (flags == 4) //not target parcel, scripted object
1785 {
1786 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1787 {
1788 if (e.OwnerID == targetID)
1789 {
1790 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
1791 if (landobject.LandData.OwnerID != e.OwnerID)
1792 {
1793 if (e.ContainsScripts())
1794 {
1795 returns.Add(e);
1796 }
1797 }
1798 }
1799 }
1800 );
1801 }
1802 foreach (SceneObjectGroup ol in returns)
1803 {
1804 ReturnObject(ol, client);
1805 }
1806 }
1807 }
1808 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
1809 {
1810 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1811 objs[0] = obj;
1812 ((Scene)client.Scene).returnObjects(objs, client.AgentId);
1813 }
1814
1744 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); 1815 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1745 1816
1746 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 1817 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
@@ -1776,7 +1847,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1776 } 1847 }
1777 } 1848 }
1778 } 1849 }
1779
1780 private void OnEndParcelFrozen(object avatar) 1850 private void OnEndParcelFrozen(object avatar)
1781 { 1851 {
1782 ScenePresence targetAvatar = (ScenePresence)avatar; 1852 ScenePresence targetAvatar = (ScenePresence)avatar;
@@ -1787,6 +1857,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1787 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); 1857 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
1788 } 1858 }
1789 1859
1860
1790 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 1861 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1791 { 1862 {
1792 ScenePresence targetAvatar = null; 1863 ScenePresence targetAvatar = null;
@@ -1806,12 +1877,13 @@ namespace OpenSim.Region.CoreModules.World.Land
1806 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && 1877 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) &&
1807 !m_scene.Permissions.IsAdministrator(client.AgentId)) 1878 !m_scene.Permissions.IsAdministrator(client.AgentId))
1808 return; 1879 return;
1880
1809 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); 1881 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
1810 1882
1811 targetAvatar.TeleportWithMomentum(pos, null); 1883 targetAvatar.TeleportWithMomentum(pos, null);
1812 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); 1884 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
1813 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); 1885 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
1814 1886
1815 if ((flags & 1) != 0) // Ban TODO: Remove magic number 1887 if ((flags & 1) != 0) // Ban TODO: Remove magic number
1816 { 1888 {
1817 LandAccessEntry entry = new LandAccessEntry(); 1889 LandAccessEntry entry = new LandAccessEntry();
@@ -1822,7 +1894,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1822 land.LandData.ParcelAccessList.Add(entry); 1894 land.LandData.ParcelAccessList.Add(entry);
1823 } 1895 }
1824 } 1896 }
1825 1897
1826 protected void InstallInterfaces() 1898 protected void InstallInterfaces()
1827 { 1899 {
1828 Command clearCommand 1900 Command clearCommand
@@ -1884,5 +1956,27 @@ namespace OpenSim.Region.CoreModules.World.Land
1884 1956
1885 MainConsole.Instance.Output(report.ToString()); 1957 MainConsole.Instance.Output(report.ToString());
1886 } 1958 }
1959
1960 public void EnforceBans(ILandObject land, ScenePresence avatar)
1961 {
1962 if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT)
1963 return;
1964
1965 if (land.IsEitherBannedOrRestricted(avatar.UUID))
1966 {
1967 if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y)))
1968 {
1969 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
1970 if (pos == null)
1971 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
1972 else
1973 ForceAvatarToPosition(avatar, (Vector3)pos);
1974 }
1975 else
1976 {
1977 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
1978 }
1979 }
1980 }
1887 } 1981 }
1888} 1982}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 5969d45..07d00c0 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -51,6 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Land
51 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; 51 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax];
52 52
53 private int m_lastSeqId = 0; 53 private int m_lastSeqId = 0;
54 private int m_expiryCounter = 0;
54 55
55 protected LandData m_landData = new LandData(); 56 protected LandData m_landData = new LandData();
56 protected Scene m_scene; 57 protected Scene m_scene;
@@ -136,6 +137,8 @@ namespace OpenSim.Region.CoreModules.World.Land
136 else 137 else
137 LandData.GroupID = UUID.Zero; 138 LandData.GroupID = UUID.Zero;
138 LandData.IsGroupOwned = is_group_owned; 139 LandData.IsGroupOwned = is_group_owned;
140
141 m_scene.EventManager.OnFrame += OnFrame;
139 } 142 }
140 143
141 #endregion 144 #endregion
@@ -194,10 +197,27 @@ namespace OpenSim.Region.CoreModules.World.Land
194 else 197 else
195 { 198 {
196 // Normal Calculations 199 // Normal Calculations
197 int parcelMax = (int)(((float)LandData.Area / 65536.0f) 200 int parcelMax = (int)((long)LandData.Area
198 * (float)m_scene.RegionInfo.ObjectCapacity 201 * (long)m_scene.RegionInfo.ObjectCapacity
199 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 202 * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus
200 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! 203 / 65536L);
204 //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax);
205 return parcelMax;
206 }
207 }
208
209 private int GetParcelBasePrimCount()
210 {
211 if (overrideParcelMaxPrimCount != null)
212 {
213 return overrideParcelMaxPrimCount(this);
214 }
215 else
216 {
217 // Normal Calculations
218 int parcelMax = (int)((long)LandData.Area
219 * (long)m_scene.RegionInfo.ObjectCapacity
220 / 65536L);
201 return parcelMax; 221 return parcelMax;
202 } 222 }
203 } 223 }
@@ -211,8 +231,9 @@ namespace OpenSim.Region.CoreModules.World.Land
211 else 231 else
212 { 232 {
213 //Normal Calculations 233 //Normal Calculations
214 int simMax = (int)(((float)LandData.SimwideArea / 65536.0f) 234 int simMax = (int)((long)LandData.SimwideArea
215 * (float)m_scene.RegionInfo.ObjectCapacity); 235 * (long)m_scene.RegionInfo.ObjectCapacity / 65536L);
236 // m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax);
216 return simMax; 237 return simMax;
217 } 238 }
218 } 239 }
@@ -249,7 +270,7 @@ namespace OpenSim.Region.CoreModules.World.Land
249 remote_client.SendLandProperties(seq_id, 270 remote_client.SendLandProperties(seq_id,
250 snap_selection, request_result, this, 271 snap_selection, request_result, this,
251 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, 272 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
252 GetParcelMaxPrimCount(), 273 GetParcelBasePrimCount(),
253 GetSimulatorMaxPrimCount(), regionFlags); 274 GetSimulatorMaxPrimCount(), regionFlags);
254 } 275 }
255 276
@@ -309,7 +330,7 @@ namespace OpenSim.Region.CoreModules.World.Land
309 330
310 allowedDelta |= (uint)(ParcelFlags.ShowDirectory | 331 allowedDelta |= (uint)(ParcelFlags.ShowDirectory |
311 ParcelFlags.AllowPublish | 332 ParcelFlags.AllowPublish |
312 ParcelFlags.MaturePublish); 333 ParcelFlags.MaturePublish) | (uint)(1 << 23);
313 } 334 }
314 335
315 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) 336 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity))
@@ -421,6 +442,19 @@ namespace OpenSim.Region.CoreModules.World.Land
421 return false; 442 return false;
422 } 443 }
423 444
445 public bool CanBeOnThisLand(UUID avatar, float posHeight)
446 {
447 if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar))
448 {
449 return false;
450 }
451 else if (IsRestrictedFromLand(avatar))
452 {
453 return false;
454 }
455 return true;
456 }
457
424 public bool HasGroupAccess(UUID avatar) 458 public bool HasGroupAccess(UUID avatar)
425 { 459 {
426 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) 460 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
@@ -1185,6 +1219,17 @@ namespace OpenSim.Region.CoreModules.World.Land
1185 1219
1186 #endregion 1220 #endregion
1187 1221
1222 private void OnFrame()
1223 {
1224 m_expiryCounter++;
1225
1226 if (m_expiryCounter >= 50)
1227 {
1228 ExpireAccessList();
1229 m_expiryCounter = 0;
1230 }
1231 }
1232
1188 private void ExpireAccessList() 1233 private void ExpireAccessList()
1189 { 1234 {
1190 List<LandAccessEntry> delete = new List<LandAccessEntry>(); 1235 List<LandAccessEntry> delete = new List<LandAccessEntry>();
@@ -1195,7 +1240,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1195 delete.Add(entry); 1240 delete.Add(entry);
1196 } 1241 }
1197 foreach (LandAccessEntry entry in delete) 1242 foreach (LandAccessEntry entry in delete)
1243 {
1198 LandData.ParcelAccessList.Remove(entry); 1244 LandData.ParcelAccessList.Remove(entry);
1245 ScenePresence presence;
1246
1247 if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
1248 {
1249 ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
1250 if (land.LandData.LocalID == LandData.LocalID)
1251 {
1252 Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
1253 presence.TeleportWithMomentum(pos, null);
1254 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
1255 }
1256 }
1257 m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
1258 }
1199 1259
1200 if (delete.Count > 0) 1260 if (delete.Count > 0)
1201 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); 1261 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this);
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index 9b51cc8..771fdd2 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -207,7 +207,7 @@ namespace OpenSim.Region.CoreModules.World.Land
207 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) 207 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts))
208 { 208 {
209 UUID landOwner = landData.OwnerID; 209 UUID landOwner = landData.OwnerID;
210 int partCount = obj.Parts.Length; 210 int partCount = obj.GetPartCount();
211 211
212 m_SimwideCounts[landOwner] += partCount; 212 m_SimwideCounts[landOwner] += partCount;
213 if (parcelCounts.Users.ContainsKey(obj.OwnerID)) 213 if (parcelCounts.Users.ContainsKey(obj.OwnerID))
@@ -597,4 +597,4 @@ namespace OpenSim.Region.CoreModules.World.Land
597 } 597 }
598 } 598 }
599 } 599 }
600} \ No newline at end of file 600}
diff --git a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
index 89f3280..f13d648 100644
--- a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
+++ b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
@@ -190,6 +190,9 @@ namespace OpenSim.Region.CoreModules.World.LightShare
190 190
191 public void SendProfileToClient(IClientAPI client, RegionLightShareData wl) 191 public void SendProfileToClient(IClientAPI client, RegionLightShareData wl)
192 { 192 {
193 if (client == null)
194 return;
195
193 if (m_enableWindlight) 196 if (m_enableWindlight)
194 { 197 {
195 if (m_scene.RegionInfo.WindlightSettings.valid) 198 if (m_scene.RegionInfo.WindlightSettings.valid)
@@ -207,7 +210,8 @@ namespace OpenSim.Region.CoreModules.World.LightShare
207 210
208 private void EventManager_OnMakeRootAgent(ScenePresence presence) 211 private void EventManager_OnMakeRootAgent(ScenePresence presence)
209 { 212 {
210 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client"); 213 if (m_enableWindlight && m_scene.RegionInfo.WindlightSettings.valid)
214 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
211 SendProfileToClient(presence.ControllingClient); 215 SendProfileToClient(presence.ControllingClient);
212 } 216 }
213 217
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index 22a53a8..28daf2f 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -177,6 +177,13 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
177 return false; 177 return false;
178 } 178 }
179 179
180 if ((perms & (uint)PermissionMask.Copy) == 0)
181 {
182 if (m_dialogModule != null)
183 m_dialogModule.SendAlertToUser(remoteClient, "This sale has been blocked by the permissions system");
184 return false;
185 }
186
180 AssetBase asset = m_scene.CreateAsset( 187 AssetBase asset = m_scene.CreateAsset(
181 group.GetPartName(localID), 188 group.GetPartName(localID),
182 group.GetPartDescription(localID), 189 group.GetPartDescription(localID),
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
index 249a40d..9c441ed 100644
--- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
+++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
@@ -29,6 +29,8 @@ using System;
29using System.Linq; 29using System.Linq;
30using System.Reflection; 30using System.Reflection;
31using System.Timers; 31using System.Timers;
32using System.IO;
33using System.Diagnostics;
32using System.Threading; 34using System.Threading;
33using System.Collections.Generic; 35using System.Collections.Generic;
34using log4net; 36using log4net;
@@ -57,13 +59,24 @@ namespace OpenSim.Region.CoreModules.World.Region
57 protected UUID m_Initiator; 59 protected UUID m_Initiator;
58 protected bool m_Notice = false; 60 protected bool m_Notice = false;
59 protected IDialogModule m_DialogModule = null; 61 protected IDialogModule m_DialogModule = null;
62 protected string m_MarkerPath = String.Empty;
63 private int[] m_CurrentAlerts = null;
60 64
61 public void Initialise(IConfigSource config) 65 public void Initialise(IConfigSource config)
62 { 66 {
67 IConfig restartConfig = config.Configs["RestartModule"];
68 if (restartConfig != null)
69 {
70 m_MarkerPath = restartConfig.GetString("MarkerPath", String.Empty);
71 }
63 } 72 }
64 73
65 public void AddRegion(Scene scene) 74 public void AddRegion(Scene scene)
66 { 75 {
76 if (m_MarkerPath != String.Empty)
77 File.Delete(Path.Combine(m_MarkerPath,
78 scene.RegionInfo.RegionID.ToString()));
79
67 m_Scene = scene; 80 m_Scene = scene;
68 81
69 scene.RegisterModuleInterface<IRestartModule>(this); 82 scene.RegisterModuleInterface<IRestartModule>(this);
@@ -122,6 +135,7 @@ namespace OpenSim.Region.CoreModules.World.Region
122 135
123 if (alerts == null) 136 if (alerts == null)
124 { 137 {
138 CreateMarkerFile();
125 m_Scene.RestartNow(); 139 m_Scene.RestartNow();
126 return; 140 return;
127 } 141 }
@@ -129,25 +143,28 @@ namespace OpenSim.Region.CoreModules.World.Region
129 m_Message = message; 143 m_Message = message;
130 m_Initiator = initiator; 144 m_Initiator = initiator;
131 m_Notice = notice; 145 m_Notice = notice;
146 m_CurrentAlerts = alerts;
132 m_Alerts = new List<int>(alerts); 147 m_Alerts = new List<int>(alerts);
133 m_Alerts.Sort(); 148 m_Alerts.Sort();
134 m_Alerts.Reverse(); 149 m_Alerts.Reverse();
135 150
136 if (m_Alerts[0] == 0) 151 if (m_Alerts[0] == 0)
137 { 152 {
153 CreateMarkerFile();
138 m_Scene.RestartNow(); 154 m_Scene.RestartNow();
139 return; 155 return;
140 } 156 }
141 157
142 int nextInterval = DoOneNotice(); 158 int nextInterval = DoOneNotice(true);
143 159
144 SetTimer(nextInterval); 160 SetTimer(nextInterval);
145 } 161 }
146 162
147 public int DoOneNotice() 163 public int DoOneNotice(bool sendOut)
148 { 164 {
149 if (m_Alerts.Count == 0 || m_Alerts[0] == 0) 165 if (m_Alerts.Count == 0 || m_Alerts[0] == 0)
150 { 166 {
167 CreateMarkerFile();
151 m_Scene.RestartNow(); 168 m_Scene.RestartNow();
152 return 0; 169 return 0;
153 } 170 }
@@ -168,34 +185,37 @@ namespace OpenSim.Region.CoreModules.World.Region
168 185
169 m_Alerts.RemoveAt(0); 186 m_Alerts.RemoveAt(0);
170 187
171 int minutes = currentAlert / 60; 188 if (sendOut)
172 string currentAlertString = String.Empty;
173 if (minutes > 0)
174 { 189 {
175 if (minutes == 1) 190 int minutes = currentAlert / 60;
176 currentAlertString += "1 minute"; 191 string currentAlertString = String.Empty;
177 else 192 if (minutes > 0)
178 currentAlertString += String.Format("{0} minutes", minutes); 193 {
194 if (minutes == 1)
195 currentAlertString += "1 minute";
196 else
197 currentAlertString += String.Format("{0} minutes", minutes);
198 if ((currentAlert % 60) != 0)
199 currentAlertString += " and ";
200 }
179 if ((currentAlert % 60) != 0) 201 if ((currentAlert % 60) != 0)
180 currentAlertString += " and "; 202 {
181 } 203 int seconds = currentAlert % 60;
182 if ((currentAlert % 60) != 0) 204 if (seconds == 1)
183 { 205 currentAlertString += "1 second";
184 int seconds = currentAlert % 60; 206 else
185 if (seconds == 1) 207 currentAlertString += String.Format("{0} seconds", seconds);
186 currentAlertString += "1 second"; 208 }
187 else
188 currentAlertString += String.Format("{0} seconds", seconds);
189 }
190 209
191 string msg = String.Format(m_Message, currentAlertString); 210 string msg = String.Format(m_Message, currentAlertString);
192 211
193 if (m_DialogModule != null && msg != String.Empty) 212 if (m_DialogModule != null && msg != String.Empty)
194 { 213 {
195 if (m_Notice) 214 if (m_Notice)
196 m_DialogModule.SendGeneralAlert(msg); 215 m_DialogModule.SendGeneralAlert(msg);
197 else 216 else
198 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg); 217 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg);
218 }
199 } 219 }
200 220
201 return currentAlert - nextAlert; 221 return currentAlert - nextAlert;
@@ -212,7 +232,25 @@ namespace OpenSim.Region.CoreModules.World.Region
212 232
213 private void OnTimer(object source, ElapsedEventArgs e) 233 private void OnTimer(object source, ElapsedEventArgs e)
214 { 234 {
215 int nextInterval = DoOneNotice(); 235 int nextInterval = DoOneNotice(true);
236
237 SetTimer(nextInterval);
238 }
239
240 public void DelayRestart(int seconds, string message)
241 {
242 if (m_CountdownTimer == null)
243 return;
244
245 m_CountdownTimer.Stop();
246 m_CountdownTimer = null;
247
248 m_Alerts = new List<int>(m_CurrentAlerts);
249 m_Alerts.Add(seconds);
250 m_Alerts.Sort();
251 m_Alerts.Reverse();
252
253 int nextInterval = DoOneNotice(false);
216 254
217 SetTimer(nextInterval); 255 SetTimer(nextInterval);
218 } 256 }
@@ -226,6 +264,9 @@ namespace OpenSim.Region.CoreModules.World.Region
226 if (m_DialogModule != null && message != String.Empty) 264 if (m_DialogModule != null && message != String.Empty)
227 m_DialogModule.SendGeneralAlert(message); 265 m_DialogModule.SendGeneralAlert(message);
228 } 266 }
267 if (m_MarkerPath != String.Empty)
268 File.Delete(Path.Combine(m_MarkerPath,
269 m_Scene.RegionInfo.RegionID.ToString()));
229 } 270 }
230 271
231 private void HandleRegionRestart(string module, string[] args) 272 private void HandleRegionRestart(string module, string[] args)
@@ -270,5 +311,25 @@ namespace OpenSim.Region.CoreModules.World.Region
270 311
271 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice); 312 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
272 } 313 }
314
315 protected void CreateMarkerFile()
316 {
317 if (m_MarkerPath == String.Empty)
318 return;
319
320 string path = Path.Combine(m_MarkerPath, m_Scene.RegionInfo.RegionID.ToString());
321 try
322 {
323 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
324 FileStream fs = File.Create(path);
325 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
326 Byte[] buf = enc.GetBytes(pidstring);
327 fs.Write(buf, 0, buf.Length);
328 fs.Close();
329 }
330 catch (Exception)
331 {
332 }
333 }
273 } 334 }
274} \ No newline at end of file 335} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index fd30c46..4d738a5 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -644,6 +644,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
644 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); 644 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised());
645 m_scene.SaveTerrain(); 645 m_scene.SaveTerrain();
646 646
647 m_scene.EventManager.TriggerTerrainUpdate();
648
647 // Clients who look at the map will never see changes after they looked at the map, so i've commented this out. 649 // Clients who look at the map will never see changes after they looked at the map, so i've commented this out.
648 //m_scene.CreateTerrainTexture(true); 650 //m_scene.CreateTerrainTexture(true);
649 } 651 }
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index ed2b06a..d38f34b 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
@@ -65,6 +65,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
65 private bool m_useAntiAliasing = false; // TODO: Make this a config option 65 private bool m_useAntiAliasing = false; // TODO: Make this a config option
66 private bool m_Enabled = false; 66 private bool m_Enabled = false;
67 67
68 private Bitmap lastImage = null;
69 private DateTime lastImageTime = DateTime.MinValue;
70
68 #region Region Module interface 71 #region Region Module interface
69 72
70 public void Initialise(IConfigSource source) 73 public void Initialise(IConfigSource source)
@@ -87,14 +90,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
87 90
88 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 91 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
89 if (renderers.Count > 0) 92 if (renderers.Count > 0)
90 { 93 m_log.Info("[MAPTILE]: Loaded prim mesher " + renderers[0]);
91 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
92 m_log.DebugFormat("[WARP 3D IMAGE MODULE]: Loaded prim mesher {0}", m_primMesher);
93 }
94 else 94 else
95 { 95 m_log.Info("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled");
96 m_log.Debug("[WARP 3D IMAGE MODULE]: No prim mesher loaded, prim rendering will be disabled");
97 }
98 96
99 m_scene.RegisterModuleInterface<IMapImageGenerator>(this); 97 m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
100 } 98 }
@@ -127,9 +125,25 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
127 125
128 public Bitmap CreateMapTile() 126 public Bitmap CreateMapTile()
129 { 127 {
128 if ((DateTime.Now - lastImageTime).TotalSeconds < 3600)
129 {
130 return lastImage.Clone(new Rectangle(0, 0, 256, 256), lastImage.PixelFormat);
131 }
132
133 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
134 if (renderers.Count > 0)
135 {
136 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
137 }
138
130 Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f); 139 Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f);
131 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize); 140 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize);
132 return CreateMapTile(viewport, false); 141 Bitmap tile = CreateMapTile(viewport, false);
142 m_primMesher = null;
143
144 lastImage = tile;
145 lastImageTime = DateTime.Now;
146 return lastImage.Clone(new Rectangle(0, 0, 256, 256), lastImage.PixelFormat);
133 } 147 }
134 148
135 public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) 149 public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 708a9a2..4c96a50 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -128,85 +128,93 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
128 128
129 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) 129 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
130 { 130 {
131 List<MapBlockData> blocks = new List<MapBlockData>(); 131 Util.FireAndForget(x =>
132 MapBlockData data;
133 if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4))
134 { 132 {
133 if (mapName.Length < 2)
134 {
135 remoteClient.SendAlertMessage("Use a search string with at least 2 characters");
136 return;
137 }
138
139 //m_log.DebugFormat("MAP NAME=({0})", mapName);
140
141 // Hack to get around the fact that ll V3 now drops the port from the
142 // map name. See https://jira.secondlife.com/browse/VWR-28570
143 //
144 // Caller, use this magic form instead:
145 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128
146 // or url encode if possible.
147 // the hacks we do with this viewer...
148 //
149 string mapNameOrig = mapName;
150 if (mapName.Contains("|"))
151 mapName = mapName.Replace('|', ':');
152 if (mapName.Contains("+"))
153 mapName = mapName.Replace('+', ' ');
154 if (mapName.Contains("!"))
155 mapName = mapName.Replace('!', '/');
156
157 // try to fetch from GridServer
158 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
159 // if (regionInfos.Count == 0)
160 // remoteClient.SendAlertMessage("Hyperlink could not be established.");
161
162 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
163 List<MapBlockData> blocks = new List<MapBlockData>();
164
165 MapBlockData data;
166 if (regionInfos.Count > 0)
167 {
168 foreach (GridRegion info in regionInfos)
169 {
170 data = new MapBlockData();
171 data.Agents = 0;
172 data.Access = info.Access;
173 if (flags == 2) // V2 sends this
174 data.MapImageId = UUID.Zero;
175 else
176 data.MapImageId = info.TerrainImage;
177 // ugh! V2-3 is very sensitive about the result being
178 // exactly the same as the requested name
179 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
180 data.Name = mapNameOrig;
181 else
182 data.Name = info.RegionName;
183 data.RegionFlags = 0; // TODO not used?
184 data.WaterHeight = 0; // not used
185 data.X = (ushort)(info.RegionLocX / Constants.RegionSize);
186 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize);
187 blocks.Add(data);
188 }
189 }
190
135 // final block, closing the search result 191 // final block, closing the search result
136 AddFinalBlock(blocks); 192 data = new MapBlockData();
193 data.Agents = 0;
194 data.Access = 255;
195 data.MapImageId = UUID.Zero;
196 data.Name = mapName;
197 data.RegionFlags = 0;
198 data.WaterHeight = 0; // not used
199 data.X = 0;
200 data.Y = 0;
201 blocks.Add(data);
137 202
138 // flags are agent flags sent from the viewer. 203 // flags are agent flags sent from the viewer.
139 // they have different values depending on different viewers, apparently 204 // they have different values depending on different viewers, apparently
140 remoteClient.SendMapBlock(blocks, flags); 205 remoteClient.SendMapBlock(blocks, flags);
141 remoteClient.SendAlertMessage("Use a search string with at least 3 characters");
142 return;
143 }
144
145 206
146 //m_log.DebugFormat("MAP NAME=({0})", mapName); 207 // send extra user messages for V3
147 208 // because the UI is very confusing
148 // Hack to get around the fact that ll V3 now drops the port from the 209 // while we don't fix the hard-coded urls
149 // map name. See https://jira.secondlife.com/browse/VWR-28570 210 if (flags == 2)
150 //
151 // Caller, use this magic form instead:
152 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128
153 // or url encode if possible.
154 // the hacks we do with this viewer...
155 //
156 string mapNameOrig = mapName;
157 if (mapName.Contains("|"))
158 mapName = mapName.Replace('|', ':');
159 if (mapName.Contains("+"))
160 mapName = mapName.Replace('+', ' ');
161 if (mapName.Contains("!"))
162 mapName = mapName.Replace('!', '/');
163
164 // try to fetch from GridServer
165 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
166
167 m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags);
168 if (regionInfos.Count > 0)
169 {
170 foreach (GridRegion info in regionInfos)
171 { 211 {
172 data = new MapBlockData(); 212 if (regionInfos.Count == 0)
173 data.Agents = 0; 213 remoteClient.SendAgentAlertMessage("No regions found with that name.", true);
174 data.Access = info.Access; 214 else if (regionInfos.Count == 1)
175 if (flags == 2) // V2 sends this 215 remoteClient.SendAgentAlertMessage("Region found!", false);
176 data.MapImageId = UUID.Zero;
177 else
178 data.MapImageId = info.TerrainImage;
179 // ugh! V2-3 is very sensitive about the result being
180 // exactly the same as the requested name
181 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
182 data.Name = mapNameOrig;
183 else
184 data.Name = info.RegionName;
185 data.RegionFlags = 0; // TODO not used?
186 data.WaterHeight = 0; // not used
187 data.X = (ushort)(info.RegionLocX / Constants.RegionSize);
188 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize);
189 blocks.Add(data);
190 } 216 }
191 } 217 });
192
193 // final block, closing the search result
194 AddFinalBlock(blocks);
195
196 // flags are agent flags sent from the viewer.
197 // they have different values depending on different viewers, apparently
198 remoteClient.SendMapBlock(blocks, flags);
199
200 // send extra user messages for V3
201 // because the UI is very confusing
202 // while we don't fix the hard-coded urls
203 if (flags == 2)
204 {
205 if (regionInfos.Count == 0)
206 remoteClient.SendAlertMessage("No regions found with that name.");
207 else if (regionInfos.Count == 1)
208 remoteClient.SendAlertMessage("Region found!");
209 }
210 } 218 }
211 219
212 private void AddFinalBlock(List<MapBlockData> blocks) 220 private void AddFinalBlock(List<MapBlockData> blocks)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index c50ab64..bf18616 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -66,7 +66,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
66 private static readonly UUID STOP_UUID = UUID.Random(); 66 private static readonly UUID STOP_UUID = UUID.Random();
67 private static readonly string m_mapLayerPath = "0001/"; 67 private static readonly string m_mapLayerPath = "0001/";
68 68
69 private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>(); 69 private ManualResetEvent queueEvent = new ManualResetEvent(false);
70 private Queue<MapRequestState> requests = new Queue<MapRequestState>();
71
72 private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false);
73 private Dictionary<UUID, Queue<MapBlockRequestData>> m_mapBlockRequests = new Dictionary<UUID, Queue<MapBlockRequestData>>();
70 74
71 protected Scene m_scene; 75 protected Scene m_scene;
72 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 76 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
@@ -74,7 +78,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
74 private int blacklistTimeout = 10*60*1000; // 10 minutes 78 private int blacklistTimeout = 10*60*1000; // 10 minutes
75 private byte[] myMapImageJPEG; 79 private byte[] myMapImageJPEG;
76 protected volatile bool m_Enabled = false; 80 protected volatile bool m_Enabled = false;
77 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>();
78 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>(); 81 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>();
79 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>(); 82 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>();
80 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>(); 83 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>();
@@ -91,7 +94,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
91 if (Util.GetConfigVarFromSections<string>( 94 if (Util.GetConfigVarFromSections<string>(
92 config, "WorldMapModule", configSections, "WorldMap") == "WorldMap") 95 config, "WorldMapModule", configSections, "WorldMap") == "WorldMap")
93 m_Enabled = true; 96 m_Enabled = true;
94 97
95 blacklistTimeout 98 blacklistTimeout
96 = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000; 99 = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000;
97 } 100 }
@@ -234,54 +237,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
234 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is 237 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
235 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. 238 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
236 239
237 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 240 //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
238 { 241 //{
239 ScenePresence avatarPresence = null; 242 // ScenePresence avatarPresence = null;
240 243
241 m_scene.TryGetScenePresence(agentID, out avatarPresence); 244 // m_scene.TryGetScenePresence(agentID, out avatarPresence);
242 245
243 if (avatarPresence != null) 246 // if (avatarPresence != null)
244 { 247 // {
245 bool lookup = false; 248 // bool lookup = false;
246 249
247 lock (cachedMapBlocks) 250 // lock (cachedMapBlocks)
248 { 251 // {
249 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) 252 // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
250 { 253 // {
251 List<MapBlockData> mapBlocks; 254 // List<MapBlockData> mapBlocks;
252 255
253 mapBlocks = cachedMapBlocks; 256 // mapBlocks = cachedMapBlocks;
254 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 257 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
255 } 258 // }
256 else 259 // else
257 { 260 // {
258 lookup = true; 261 // lookup = true;
259 } 262 // }
260 } 263 // }
261 if (lookup) 264 // if (lookup)
262 { 265 // {
263 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 266 // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
264 267
265 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 268 // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
266 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, 269 // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
267 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, 270 // (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
268 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, 271 // (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
269 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); 272 // (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
270 foreach (GridRegion r in regions) 273 // foreach (GridRegion r in regions)
271 { 274 // {
272 MapBlockData block = new MapBlockData(); 275 // MapBlockData block = new MapBlockData();
273 MapBlockFromGridRegion(block, r, 0); 276 // MapBlockFromGridRegion(block, r, 0);
274 mapBlocks.Add(block); 277 // mapBlocks.Add(block);
275 } 278 // }
276 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 279 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
277 280
278 lock (cachedMapBlocks) 281 // lock (cachedMapBlocks)
279 cachedMapBlocks = mapBlocks; 282 // cachedMapBlocks = mapBlocks;
280 283
281 cachedTime = Util.UnixTimeSinceEpoch(); 284 // cachedTime = Util.UnixTimeSinceEpoch();
282 } 285 // }
283 } 286 // }
284 } 287 //}
285 288
286 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 289 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
287 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 290 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
@@ -308,8 +311,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
308 protected static OSDMapLayer GetOSDMapLayerResponse() 311 protected static OSDMapLayer GetOSDMapLayerResponse()
309 { 312 {
310 OSDMapLayer mapLayer = new OSDMapLayer(); 313 OSDMapLayer mapLayer = new OSDMapLayer();
311 mapLayer.Right = 5000; 314 mapLayer.Right = 2048;
312 mapLayer.Top = 5000; 315 mapLayer.Top = 2048;
313 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); 316 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
314 317
315 return mapLayer; 318 return mapLayer;
@@ -338,6 +341,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
338 { 341 {
339 m_rootAgents.Remove(AgentId); 342 m_rootAgents.Remove(AgentId);
340 } 343 }
344 lock (m_mapBlockRequestEvent)
345 {
346 if (m_mapBlockRequests.ContainsKey(AgentId))
347 m_mapBlockRequests.Remove(AgentId);
348 }
341 } 349 }
342 #endregion 350 #endregion
343 351
@@ -360,6 +368,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
360 ThreadPriority.BelowNormal, 368 ThreadPriority.BelowNormal,
361 true, 369 true,
362 true); 370 true);
371 Watchdog.StartThread(
372 MapBlockSendThread,
373 string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
374 ThreadPriority.BelowNormal,
375 true,
376 true);
363 } 377 }
364 378
365 /// <summary> 379 /// <summary>
@@ -375,7 +389,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
375 st.itemtype=0; 389 st.itemtype=0;
376 st.regionhandle=0; 390 st.regionhandle=0;
377 391
378 requests.Enqueue(st); 392 lock (requests)
393 {
394 queueEvent.Set();
395 requests.Enqueue(st);
396 }
397
398 MapBlockRequestData req = new MapBlockRequestData();
399
400 req.client = null;
401 req.minX = 0;
402 req.maxX = 0;
403 req.minY = 0;
404 req.maxY = 0;
405 req.flags = 0;
406
407 lock (m_mapBlockRequestEvent)
408 {
409 m_mapBlockRequests[UUID.Zero] = new Queue<MapBlockRequestData>();
410 m_mapBlockRequests[UUID.Zero].Enqueue(req);
411 m_mapBlockRequestEvent.Set();
412 }
379 } 413 }
380 414
381 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 415 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
@@ -531,7 +565,21 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
531 { 565 {
532 while (true) 566 while (true)
533 { 567 {
534 MapRequestState st = requests.Dequeue(1000); 568 MapRequestState st = new MapRequestState();
569 bool valid = false;
570 queueEvent.WaitOne();
571 lock (requests)
572 {
573 if (requests.Count > 0)
574 {
575 st = requests.Dequeue();
576 valid = true;
577 }
578 if (requests.Count == 0)
579 queueEvent.Reset();
580 }
581 if (!valid)
582 continue;
535 583
536 // end gracefully 584 // end gracefully
537 if (st.agentID == STOP_UUID) 585 if (st.agentID == STOP_UUID)
@@ -549,13 +597,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
549 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) 597 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
550 { 598 {
551 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break 599 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
552 Thread.Sleep(80); 600 Thread.Sleep(100);
553 601
554 RequestMapItemsDelegate d = RequestMapItemsAsync;
555 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
556 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
557 //RequestMapItemsCompleted(response);
558 Interlocked.Increment(ref nAsyncRequests); 602 Interlocked.Increment(ref nAsyncRequests);
603 Util.FireAndForget(x =>
604 {
605 RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
606 });
559 } 607 }
560 } 608 }
561 609
@@ -577,110 +625,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
577 /// <param name="state"></param> 625 /// <param name="state"></param>
578 public void EnqueueMapItemRequest(MapRequestState state) 626 public void EnqueueMapItemRequest(MapRequestState state)
579 { 627 {
580 requests.Enqueue(state); 628 lock (requests)
581 }
582
583 /// <summary>
584 /// Sends the mapitem response to the IClientAPI
585 /// </summary>
586 /// <param name="response">The OSDMap Response for the mapitem</param>
587 private void RequestMapItemsCompleted(IAsyncResult iar)
588 {
589 AsyncResult result = (AsyncResult)iar;
590 RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
591
592 OSDMap response = (OSDMap)icon.EndInvoke(iar);
593
594 Interlocked.Decrement(ref nAsyncRequests);
595
596 if (!response.ContainsKey("requestID"))
597 return;
598
599 UUID requestID = response["requestID"].AsUUID();
600
601 if (requestID != UUID.Zero)
602 { 629 {
603 MapRequestState mrs = new MapRequestState(); 630 queueEvent.Set();
604 mrs.agentID = UUID.Zero; 631 requests.Enqueue(state);
605 lock (m_openRequests)
606 {
607 if (m_openRequests.ContainsKey(requestID))
608 {
609 mrs = m_openRequests[requestID];
610 m_openRequests.Remove(requestID);
611 }
612 }
613
614 if (mrs.agentID != UUID.Zero)
615 {
616 ScenePresence av = null;
617 m_scene.TryGetScenePresence(mrs.agentID, out av);
618 if (av != null)
619 {
620 if (response.ContainsKey(mrs.itemtype.ToString()))
621 {
622 List<mapItemReply> returnitems = new List<mapItemReply>();
623 OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()];
624 for (int i = 0; i < itemarray.Count; i++)
625 {
626 OSDMap mapitem = (OSDMap)itemarray[i];
627 mapItemReply mi = new mapItemReply();
628 mi.x = (uint)mapitem["X"].AsInteger();
629 mi.y = (uint)mapitem["Y"].AsInteger();
630 mi.id = mapitem["ID"].AsUUID();
631 mi.Extra = mapitem["Extra"].AsInteger();
632 mi.Extra2 = mapitem["Extra2"].AsInteger();
633 mi.name = mapitem["Name"].AsString();
634 returnitems.Add(mi);
635 }
636 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
637 }
638
639 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
640 uint itemtype = 7;
641
642 if (response.ContainsKey(itemtype.ToString()))
643 {
644 List<mapItemReply> returnitems = new List<mapItemReply>();
645 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
646 for (int i = 0; i < itemarray.Count; i++)
647 {
648 OSDMap mapitem = (OSDMap)itemarray[i];
649 mapItemReply mi = new mapItemReply();
650 mi.x = (uint)mapitem["X"].AsInteger();
651 mi.y = (uint)mapitem["Y"].AsInteger();
652 mi.id = mapitem["ID"].AsUUID();
653 mi.Extra = mapitem["Extra"].AsInteger();
654 mi.Extra2 = mapitem["Extra2"].AsInteger();
655 mi.name = mapitem["Name"].AsString();
656 returnitems.Add(mi);
657 }
658 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
659 }
660
661 // Service 1 (MAP_ITEM_TELEHUB)
662 itemtype = 1;
663
664 if (response.ContainsKey(itemtype.ToString()))
665 {
666 List<mapItemReply> returnitems = new List<mapItemReply>();
667 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
668 for (int i = 0; i < itemarray.Count; i++)
669 {
670 OSDMap mapitem = (OSDMap)itemarray[i];
671 mapItemReply mi = new mapItemReply();
672 mi.x = (uint)mapitem["X"].AsInteger();
673 mi.y = (uint)mapitem["Y"].AsInteger();
674 mi.id = mapitem["ID"].AsUUID();
675 mi.Extra = mapitem["Extra"].AsInteger();
676 mi.Extra2 = mapitem["Extra2"].AsInteger();
677 mi.name = mapitem["Name"].AsString();
678 returnitems.Add(mi);
679 }
680 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
681 }
682 }
683 }
684 } 632 }
685 } 633 }
686 634
@@ -707,8 +655,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
707 EnqueueMapItemRequest(st); 655 EnqueueMapItemRequest(st);
708 } 656 }
709 657
710 private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
711 uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
712 /// <summary> 658 /// <summary>
713 /// Does the actual remote mapitem request 659 /// Does the actual remote mapitem request
714 /// This should be called from an asynchronous thread 660 /// This should be called from an asynchronous thread
@@ -723,7 +669,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
723 /// <param name="itemtype">passed in from packet</param> 669 /// <param name="itemtype">passed in from packet</param>
724 /// <param name="regionhandle">Region we're looking up</param> 670 /// <param name="regionhandle">Region we're looking up</param>
725 /// <returns></returns> 671 /// <returns></returns>
726 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 672 private void RequestMapItemsAsync(UUID id, uint flags,
727 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 673 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
728 { 674 {
729// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); 675// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
@@ -746,7 +692,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
746 } 692 }
747 693
748 if (blacklisted) 694 if (blacklisted)
749 return new OSDMap(); 695 {
696 Interlocked.Decrement(ref nAsyncRequests);
697 return;
698 }
750 699
751 UUID requestID = UUID.Random(); 700 UUID requestID = UUID.Random();
752 lock (m_cachedRegionMapItemsAddress) 701 lock (m_cachedRegionMapItemsAddress)
@@ -754,6 +703,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
754 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) 703 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
755 httpserver = m_cachedRegionMapItemsAddress[regionhandle]; 704 httpserver = m_cachedRegionMapItemsAddress[regionhandle];
756 } 705 }
706
757 if (httpserver.Length == 0) 707 if (httpserver.Length == 0)
758 { 708 {
759 uint x = 0, y = 0; 709 uint x = 0, y = 0;
@@ -798,18 +748,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
798 748
799 // Can't find the http server 749 // Can't find the http server
800 if (httpserver.Length == 0 || blacklisted) 750 if (httpserver.Length == 0 || blacklisted)
801 return new OSDMap(); 751 {
802 752 Interlocked.Decrement(ref nAsyncRequests);
803 MapRequestState mrs = new MapRequestState(); 753 return;
804 mrs.agentID = id; 754 }
805 mrs.EstateID = EstateID;
806 mrs.flags = flags;
807 mrs.godlike = godlike;
808 mrs.itemtype=itemtype;
809 mrs.regionhandle = regionhandle;
810
811 lock (m_openRequests)
812 m_openRequests.Add(requestID, mrs);
813 755
814 WebRequest mapitemsrequest = null; 756 WebRequest mapitemsrequest = null;
815 try 757 try
@@ -819,7 +761,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
819 catch (Exception e) 761 catch (Exception e)
820 { 762 {
821 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); 763 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e);
822 return new OSDMap(); 764 Interlocked.Decrement(ref nAsyncRequests);
765 return;
823 } 766 }
824 767
825 mapitemsrequest.Method = "POST"; 768 mapitemsrequest.Method = "POST";
@@ -844,7 +787,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
844 catch (WebException ex) 787 catch (WebException ex)
845 { 788 {
846 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); 789 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message);
847 responseMap["connect"] = OSD.FromBoolean(false);
848 lock (m_blacklistedurls) 790 lock (m_blacklistedurls)
849 { 791 {
850 if (!m_blacklistedurls.ContainsKey(httpserver)) 792 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -853,13 +795,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
853 795
854 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 796 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
855 797
856 return responseMap; 798 Interlocked.Decrement(ref nAsyncRequests);
799 return;
857 } 800 }
858 catch 801 catch
859 { 802 {
860 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 803 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
861 responseMap["connect"] = OSD.FromBoolean(false); 804 Interlocked.Decrement(ref nAsyncRequests);
862 return responseMap; 805 return;
863 } 806 }
864 finally 807 finally
865 { 808 {
@@ -868,26 +811,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
868 } 811 }
869 812
870 string response_mapItems_reply = null; 813 string response_mapItems_reply = null;
871 { 814 { // get the response
815 StreamReader sr = null;
872 try 816 try
873 { 817 {
874 using (WebResponse webResponse = mapitemsrequest.GetResponse()) 818 WebResponse webResponse = mapitemsrequest.GetResponse();
819 if (webResponse != null)
875 { 820 {
876 if (webResponse != null) 821 sr = new StreamReader(webResponse.GetResponseStream());
877 { 822 response_mapItems_reply = sr.ReadToEnd().Trim();
878 using (Stream s = webResponse.GetResponseStream()) 823 }
879 using (StreamReader sr = new StreamReader(s)) 824 else
880 response_mapItems_reply = sr.ReadToEnd().Trim(); 825 {
881 } 826 Interlocked.Decrement(ref nAsyncRequests);
882 else 827 return;
883 { 828 }
884 return new OSDMap();
885 }
886 }
887 } 829 }
888 catch (WebException) 830 catch (WebException)
889 { 831 {
890 responseMap["connect"] = OSD.FromBoolean(false);
891 lock (m_blacklistedurls) 832 lock (m_blacklistedurls)
892 { 833 {
893 if (!m_blacklistedurls.ContainsKey(httpserver)) 834 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -896,19 +837,25 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
896 837
897 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 838 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
898 839
899 return responseMap; 840 Interlocked.Decrement(ref nAsyncRequests);
841 return;
900 } 842 }
901 catch 843 catch
902 { 844 {
903 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 845 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
904 responseMap["connect"] = OSD.FromBoolean(false);
905 lock (m_blacklistedregions) 846 lock (m_blacklistedregions)
906 { 847 {
907 if (!m_blacklistedregions.ContainsKey(regionhandle)) 848 if (!m_blacklistedregions.ContainsKey(regionhandle))
908 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 849 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
909 } 850 }
910 851
911 return responseMap; 852 Interlocked.Decrement(ref nAsyncRequests);
853 return;
854 }
855 finally
856 {
857 if (sr != null)
858 sr.Close();
912 } 859 }
913 860
914 OSD rezResponse = null; 861 OSD rezResponse = null;
@@ -922,15 +869,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
922 catch (Exception ex) 869 catch (Exception ex)
923 { 870 {
924 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); 871 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message);
925 responseMap["connect"] = OSD.FromBoolean(false);
926
927 lock (m_blacklistedregions) 872 lock (m_blacklistedregions)
928 { 873 {
929 if (!m_blacklistedregions.ContainsKey(regionhandle)) 874 if (!m_blacklistedregions.ContainsKey(regionhandle))
930 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 875 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
931 } 876 }
932 877
933 return responseMap; 878 Interlocked.Decrement(ref nAsyncRequests);
879 return;
934 } 880 }
935 } 881 }
936 882
@@ -944,7 +890,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
944 } 890 }
945 } 891 }
946 892
947 return responseMap; 893 Interlocked.Decrement(ref nAsyncRequests);
894
895 if (id != UUID.Zero)
896 {
897 ScenePresence av = null;
898 m_scene.TryGetScenePresence(id, out av);
899 if (av != null)
900 {
901 if (responseMap.ContainsKey(itemtype.ToString()))
902 {
903 List<mapItemReply> returnitems = new List<mapItemReply>();
904 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
905 for (int i = 0; i < itemarray.Count; i++)
906 {
907 OSDMap mapitem = (OSDMap)itemarray[i];
908 mapItemReply mi = new mapItemReply();
909 mi.x = (uint)mapitem["X"].AsInteger();
910 mi.y = (uint)mapitem["Y"].AsInteger();
911 mi.id = mapitem["ID"].AsUUID();
912 mi.Extra = mapitem["Extra"].AsInteger();
913 mi.Extra2 = mapitem["Extra2"].AsInteger();
914 mi.name = mapitem["Name"].AsString();
915 returnitems.Add(mi);
916 }
917 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
918 }
919
920 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
921 itemtype = 7;
922
923 if (responseMap.ContainsKey(itemtype.ToString()))
924 {
925 List<mapItemReply> returnitems = new List<mapItemReply>();
926 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
927 for (int i = 0; i < itemarray.Count; i++)
928 {
929 OSDMap mapitem = (OSDMap)itemarray[i];
930 mapItemReply mi = new mapItemReply();
931 mi.x = (uint)mapitem["X"].AsInteger();
932 mi.y = (uint)mapitem["Y"].AsInteger();
933 mi.id = mapitem["ID"].AsUUID();
934 mi.Extra = mapitem["Extra"].AsInteger();
935 mi.Extra2 = mapitem["Extra2"].AsInteger();
936 mi.name = mapitem["Name"].AsString();
937 returnitems.Add(mi);
938 }
939 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
940 }
941
942 // Service 1 (MAP_ITEM_TELEHUB)
943 itemtype = 1;
944
945 if (responseMap.ContainsKey(itemtype.ToString()))
946 {
947 List<mapItemReply> returnitems = new List<mapItemReply>();
948 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
949 for (int i = 0; i < itemarray.Count; i++)
950 {
951 OSDMap mapitem = (OSDMap)itemarray[i];
952 mapItemReply mi = new mapItemReply();
953 mi.x = (uint)mapitem["X"].AsInteger();
954 mi.y = (uint)mapitem["Y"].AsInteger();
955 mi.id = mapitem["ID"].AsUUID();
956 mi.Extra = mapitem["Extra"].AsInteger();
957 mi.Extra2 = mapitem["Extra2"].AsInteger();
958 mi.name = mapitem["Name"].AsString();
959 returnitems.Add(mi);
960 }
961 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
962 }
963 }
964 }
948 } 965 }
949 966
950 /// <summary> 967 /// <summary>
@@ -954,7 +971,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
954 /// <param name="minY"></param> 971 /// <param name="minY"></param>
955 /// <param name="maxX"></param> 972 /// <param name="maxX"></param>
956 /// <param name="maxY"></param> 973 /// <param name="maxY"></param>
957 public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 974 public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
958 { 975 {
959 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); 976 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
960 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible 977 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible
@@ -1007,21 +1024,91 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1007 1024
1008 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 1025 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1009 { 1026 {
1027 MapBlockRequestData req = new MapBlockRequestData();
1028
1029 req.client = remoteClient;
1030 req.minX = minX;
1031 req.maxX = maxX;
1032 req.minY = minY;
1033 req.maxY = maxY;
1034 req.flags = flag;
1035
1036 lock (m_mapBlockRequestEvent)
1037 {
1038 if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId))
1039 m_mapBlockRequests[remoteClient.AgentId] = new Queue<MapBlockRequestData>();
1040 m_mapBlockRequests[remoteClient.AgentId].Enqueue(req);
1041 m_mapBlockRequestEvent.Set();
1042 }
1043
1044 return new List<MapBlockData>();
1045 }
1046
1047 protected void MapBlockSendThread()
1048 {
1049 while (true)
1050 {
1051 List<MapBlockRequestData> thisRunData = new List<MapBlockRequestData>();
1052
1053 m_mapBlockRequestEvent.WaitOne();
1054 lock (m_mapBlockRequestEvent)
1055 {
1056 int total = 0;
1057 foreach (Queue<MapBlockRequestData> q in m_mapBlockRequests.Values)
1058 {
1059 if (q.Count > 0)
1060 thisRunData.Add(q.Dequeue());
1061
1062 total += q.Count;
1063 }
1064
1065 if (total == 0)
1066 m_mapBlockRequestEvent.Reset();
1067 }
1068
1069 foreach (MapBlockRequestData req in thisRunData)
1070 {
1071 // Null client stops thread
1072 if (req.client == null)
1073 return;
1074
1075 GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags);
1076 }
1077
1078 Thread.Sleep(50);
1079 }
1080 }
1081
1082 protected virtual List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1083 {
1084 List<MapBlockData> allBlocks = new List<MapBlockData>();
1010 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1085 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1011 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1086 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1012 (minX - 4) * (int)Constants.RegionSize, 1087 minX * (int)Constants.RegionSize,
1013 (maxX + 4) * (int)Constants.RegionSize, 1088 maxX * (int)Constants.RegionSize,
1014 (minY - 4) * (int)Constants.RegionSize, 1089 minY * (int)Constants.RegionSize,
1015 (maxY + 4) * (int)Constants.RegionSize); 1090 maxY * (int)Constants.RegionSize);
1091// (minX - 4) * (int)Constants.RegionSize,
1092// (maxX + 4) * (int)Constants.RegionSize,
1093// (minY - 4) * (int)Constants.RegionSize,
1094// (maxY + 4) * (int)Constants.RegionSize);
1016 foreach (GridRegion r in regions) 1095 foreach (GridRegion r in regions)
1017 { 1096 {
1018 MapBlockData block = new MapBlockData(); 1097 MapBlockData block = new MapBlockData();
1019 MapBlockFromGridRegion(block, r, flag); 1098 MapBlockFromGridRegion(block, r, flag);
1020 mapBlocks.Add(block); 1099 mapBlocks.Add(block);
1100 allBlocks.Add(block);
1101 if (mapBlocks.Count >= 10)
1102 {
1103 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1104 mapBlocks.Clear();
1105 Thread.Sleep(50);
1106 }
1021 } 1107 }
1022 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); 1108 if (mapBlocks.Count > 0)
1109 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1023 1110
1024 return mapBlocks; 1111 return allBlocks;
1025 } 1112 }
1026 1113
1027 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) 1114 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag)
@@ -1245,7 +1332,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1245 } 1332 }
1246 else 1333 else
1247 { 1334 {
1248 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); 1335 OSDArray responsearr = new OSDArray(); // Don't preallocate. MT (m_scene.GetRootAgentCount());
1249 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 1336 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1250 { 1337 {
1251 OSDMap responsemapdata = new OSDMap(); 1338 OSDMap responsemapdata = new OSDMap();
@@ -1421,6 +1508,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1421 { 1508 {
1422 m_rootAgents.Remove(avatar.UUID); 1509 m_rootAgents.Remove(avatar.UUID);
1423 } 1510 }
1511
1512 lock (m_mapBlockRequestEvent)
1513 {
1514 if (m_mapBlockRequests.ContainsKey(avatar.UUID))
1515 m_mapBlockRequests.Remove(avatar.UUID);
1516 }
1424 } 1517 }
1425 1518
1426 public void OnRegionUp(GridRegion otherRegion) 1519 public void OnRegionUp(GridRegion otherRegion)
@@ -1465,9 +1558,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1465 Color background = Color.FromArgb(0, 0, 0, 0); 1558 Color background = Color.FromArgb(0, 0, 0, 0);
1466 SolidBrush transparent = new SolidBrush(background); 1559 SolidBrush transparent = new SolidBrush(background);
1467 Graphics g = Graphics.FromImage(overlay); 1560 Graphics g = Graphics.FromImage(overlay);
1468 g.FillRectangle(transparent, 0, 0, 256, 256); 1561 g.FillRectangle(transparent, 0, 0, 255, 255);
1469 1562
1470 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); 1563 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9));
1564 Pen grey = new Pen(Color.FromArgb(255, 92, 92, 92));
1471 1565
1472 foreach (ILandObject land in parcels) 1566 foreach (ILandObject land in parcels)
1473 { 1567 {
@@ -1475,8 +1569,42 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1475 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) 1569 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0)
1476 { 1570 {
1477 landForSale = true; 1571 landForSale = true;
1572
1573 bool[,] landBitmap = land.GetLandBitmap();
1574
1575 for (int x = 0 ; x < 64 ; x++)
1576 {
1577 for (int y = 0 ; y < 64 ; y++)
1578 {
1579 if (landBitmap[x, y])
1580 {
1581 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1582
1583 if (x > 0)
1584 {
1585 if ((saleBitmap[x - 1, y] || landBitmap[x - 1, y]) == false)
1586 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4, 255 - (y * 4));
1587 }
1588 if (y > 0)
1589 {
1590 if ((saleBitmap[x, y-1] || landBitmap[x, y-1]) == false)
1591 g.DrawLine(grey, x * 4, 255 - (y * 4), x * 4 + 3, 255 - (y * 4));
1592 }
1593 if (x < 63)
1594 {
1595 if ((saleBitmap[x + 1, y] || landBitmap[x + 1, y]) == false)
1596 g.DrawLine(grey, x * 4 + 3, 252 - (y * 4), x * 4 + 3, 255 - (y * 4));
1597 }
1598 if (y < 63)
1599 {
1600 if ((saleBitmap[x, y + 1] || landBitmap[x, y + 1]) == false)
1601 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4 + 3, 252 - (y * 4));
1602 }
1603 }
1604 }
1605 }
1478 1606
1479 saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); 1607 saleBitmap = land.MergeLandBitmaps(saleBitmap, landBitmap);
1480 } 1608 }
1481 } 1609 }
1482 1610
@@ -1488,15 +1616,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1488 1616
1489 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); 1617 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName);
1490 1618
1491 for (int x = 0 ; x < 64 ; x++)
1492 {
1493 for (int y = 0 ; y < 64 ; y++)
1494 {
1495 if (saleBitmap[x, y])
1496 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1497 }
1498 }
1499
1500 try 1619 try
1501 { 1620 {
1502 return OpenJPEG.EncodeFromImage(overlay, true); 1621 return OpenJPEG.EncodeFromImage(overlay, true);
@@ -1518,4 +1637,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1518 public uint itemtype; 1637 public uint itemtype;
1519 public ulong regionhandle; 1638 public ulong regionhandle;
1520 } 1639 }
1640
1641 public struct MapBlockRequestData
1642 {
1643 public IClientAPI client;
1644 public int minX;
1645 public int minY;
1646 public int maxX;
1647 public int maxY;
1648 public uint flags;
1649 }
1521} 1650}