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.cs40
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs31
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandChannel.cs32
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs767
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs215
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RestartModule.cs127
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs176
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/Effects/ChannelDigger.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/Effects/CookieCutter.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/FlattenArea.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/LowerArea.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/NoiseArea.cs13
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RaiseArea.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RevertArea.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/SmoothArea.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/ITerrainFloodEffect.cs3
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/ITerrainPaintableEffect.cs3
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/ErodeSphere.cs29
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/FlattenSphere.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/LowerSphere.cs28
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/NoiseSphere.cs13
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/OlsenSphere.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RaiseSphere.cs30
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RevertSphere.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/SmoothSphere.cs16
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/WeatherSphere.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs474
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs54
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs119
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs674
42 files changed, 1734 insertions, 1302 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 9c6706f..406f4a8 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -160,10 +160,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
160 160
161 private IAssetService m_assetService = null; 161 private IAssetService m_assetService = null;
162 162
163
164 private UUID m_defaultUser; 163 private UUID m_defaultUser;
165 164
166 public ArchiveReadRequest(Scene scene, string loadPath, Guid requestId, Dictionary<string,object>options) 165 public ArchiveReadRequest(Scene scene, string loadPath, Guid requestId, Dictionary<string, object> options)
167 { 166 {
168 m_rootScene = scene; 167 m_rootScene = scene;
169 168
@@ -172,7 +171,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
172 m_defaultUser = (UUID)options["default-user"]; 171 m_defaultUser = (UUID)options["default-user"];
173 m_log.InfoFormat("Using User {0} as default user", m_defaultUser.ToString()); 172 m_log.InfoFormat("Using User {0} as default user", m_defaultUser.ToString());
174 } 173 }
175 else 174 else
176 { 175 {
177 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner; 176 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner;
178 } 177 }
@@ -189,8 +188,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
189 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?"); 188 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
190 m_log.Error(e); 189 m_log.Error(e);
191 } 190 }
192 191
193 m_errorMessage = String.Empty; 192 m_errorMessage = String.Empty;
193
194 m_merge = options.ContainsKey("merge"); 194 m_merge = options.ContainsKey("merge");
195 m_forceTerrain = options.ContainsKey("force-terrain"); 195 m_forceTerrain = options.ContainsKey("force-terrain");
196 m_forceParcels = options.ContainsKey("force-parcels"); 196 m_forceParcels = options.ContainsKey("force-parcels");
@@ -199,10 +199,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
199 m_requestId = requestId; 199 m_requestId = requestId;
200 m_displacement = options.ContainsKey("displacement") ? (Vector3)options["displacement"] : Vector3.Zero; 200 m_displacement = options.ContainsKey("displacement") ? (Vector3)options["displacement"] : Vector3.Zero;
201 m_rotation = options.ContainsKey("rotation") ? (float)options["rotation"] : 0f; 201 m_rotation = options.ContainsKey("rotation") ? (float)options["rotation"] : 0f;
202 m_rotationCenter = options.ContainsKey("rotation-center") ? (Vector3)options["rotation-center"] 202 m_rotationCenter = options.ContainsKey("rotation-center") ? (Vector3)options["rotation-center"]
203 : new Vector3(scene.RegionInfo.RegionSizeX / 2f, scene.RegionInfo.RegionSizeY / 2f, 0f); 203 : new Vector3(scene.RegionInfo.RegionSizeX / 2f, scene.RegionInfo.RegionSizeY / 2f, 0f);
204 204
205 // Zero can never be a valid user or group id 205 // Zero can never be a valid user id (or group)
206 m_validUserUuids[UUID.Zero] = false; 206 m_validUserUuids[UUID.Zero] = false;
207 m_validGroupUuids[UUID.Zero] = false; 207 m_validGroupUuids[UUID.Zero] = false;
208 208
@@ -210,7 +210,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
210 m_assetService = m_rootScene.AssetService; 210 m_assetService = m_rootScene.AssetService;
211 } 211 }
212 212
213 public ArchiveReadRequest(Scene scene, Stream loadStream, Guid requestId, Dictionary<string, object>options) 213 public ArchiveReadRequest(Scene scene, Stream loadStream, Guid requestId, Dictionary<string, object> options)
214 { 214 {
215 m_rootScene = scene; 215 m_rootScene = scene;
216 m_loadPath = null; 216 m_loadPath = null;
@@ -220,7 +220,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
220 m_requestId = requestId; 220 m_requestId = requestId;
221 221
222 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner; 222 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner;
223 223
224 // Zero can never be a valid user id 224 // Zero can never be a valid user id
225 m_validUserUuids[UUID.Zero] = false; 225 m_validUserUuids[UUID.Zero] = false;
226 226
@@ -523,7 +523,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
523 } 523 }
524 } 524 }
525 525
526
527 bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero); 526 bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero);
528 527
529 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned 528 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned
@@ -600,6 +599,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
600 // being no copy/no mod for everyone 599 // being no copy/no mod for everyone
601 lock (part.TaskInventory) 600 lock (part.TaskInventory)
602 { 601 {
602 // And zap any troublesome sit target information
603 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
604 part.SitTargetPosition = new Vector3(0, 0, 0);
605
606 // Fix ownership/creator of inventory items
607 // Not doing so results in inventory items
608 // being no copy/no mod for everyone
609 part.TaskInventory.LockItemsForRead(true);
610
603 TaskInventoryDictionary inv = part.TaskInventory; 611 TaskInventoryDictionary inv = part.TaskInventory;
604 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) 612 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
605 { 613 {
@@ -620,11 +628,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
620 if (!ResolveGroupUuid(kvp.Value.GroupID)) 628 if (!ResolveGroupUuid(kvp.Value.GroupID))
621 kvp.Value.GroupID = UUID.Zero; 629 kvp.Value.GroupID = UUID.Zero;
622 } 630 }
631 part.TaskInventory.LockItemsForRead(false);
632
623 } 633 }
624 } 634 }
625 } 635 }
626 636
627
628 /// <summary> 637 /// <summary>
629 /// Load serialized parcels. 638 /// Load serialized parcels.
630 /// </summary> 639 /// </summary>
@@ -645,7 +654,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
645 parcel.AABBMin += parcelDisp; 654 parcel.AABBMin += parcelDisp;
646 parcel.AABBMax += parcelDisp; 655 parcel.AABBMax += parcelDisp;
647 } 656 }
648 657
649 // Validate User and Group UUID's 658 // Validate User and Group UUID's
650 659
651 if (!ResolveGroupUuid(parcel.GroupID)) 660 if (!ResolveGroupUuid(parcel.GroupID))
@@ -660,14 +669,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
660 } 669 }
661 else 670 else
662 { 671 {
663 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; 672 parcel.OwnerID = m_defaultUser;
673 parcel.GroupID = UUID.Zero;
664 parcel.IsGroupOwned = false; 674 parcel.IsGroupOwned = false;
665 } 675 }
666 } 676 }
667 else 677 else
668 { 678 {
669 if (!ResolveUserUuid(scene, parcel.OwnerID)) 679 if (!ResolveUserUuid(scene, parcel.OwnerID))
670 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; 680 parcel.OwnerID = m_defaultUser;
681
682 if (!ResolveGroupUuid(parcel.GroupID))
683 parcel.GroupID = UUID.Zero;
671 } 684 }
672 685
673 List<LandAccessEntry> accessList = new List<LandAccessEntry>(); 686 List<LandAccessEntry> accessList = new List<LandAccessEntry>();
@@ -918,7 +931,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
918 private bool LoadTerrain(Scene scene, string terrainPath, byte[] data) 931 private bool LoadTerrain(Scene scene, string terrainPath, byte[] data)
919 { 932 {
920 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); 933 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
921
922 using (MemoryStream ms = new MemoryStream(data)) 934 using (MemoryStream ms = new MemoryStream(data))
923 { 935 {
924 if (m_displacement != Vector3.Zero || m_rotation != 0f) 936 if (m_displacement != Vector3.Zero || m_rotation != 0f)
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index 6a09caf..4178a57 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -111,17 +111,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
111 String defaultUser = ""; 111 String defaultUser = "";
112 float rotation = 0f; 112 float rotation = 0f;
113 Vector3 rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0); 113 Vector3 rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0);
114 114
115
115 OptionSet options = new OptionSet(); 116 OptionSet options = new OptionSet();
116 options.Add("m|merge", delegate (string v) { mergeOar = (v != null); }); 117 options.Add("m|merge", delegate(string v) { mergeOar = (v != null); });
117 options.Add("s|skip-assets", delegate (string v) { skipAssets = (v != null); }); 118 options.Add("s|skip-assets", delegate(string v) { skipAssets = (v != null); });
118 options.Add("force-terrain", delegate (string v) { forceTerrain = (v != null); }); 119 options.Add("force-terrain", delegate(string v) { forceTerrain = (v != null); });
119 options.Add("forceterrain", delegate (string v) { forceTerrain = (v != null); }); // downward compatibility 120 options.Add("forceterrain", delegate(string v) { forceTerrain = (v != null); }); // downward compatibility
120 options.Add("force-parcels", delegate (string v) { forceParcels = (v != null); }); 121 options.Add("force-parcels", delegate(string v) { forceParcels = (v != null); });
121 options.Add("forceparcels", delegate (string v) { forceParcels = (v != null); }); // downward compatibility 122 options.Add("forceparcels", delegate(string v) { forceParcels = (v != null); }); // downward compatibility
122 options.Add("no-objects", delegate (string v) { noObjects = (v != null); }); 123 options.Add("no-objects", delegate(string v) { noObjects = (v != null); });
123 options.Add("default-user=", delegate(string v) { defaultUser = (v == null) ? "" : v; }); 124 options.Add("default-user=", delegate(string v) { defaultUser = (v == null) ? "" : v; });
124 options.Add("displacement=", delegate (string v) { 125 options.Add("displacement=", delegate(string v)
126 {
125 try 127 try
126 { 128 {
127 displacement = v == null ? Vector3.Zero : Vector3.Parse(v); 129 displacement = v == null ? Vector3.Zero : Vector3.Parse(v);
@@ -148,7 +150,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
148 // Convert to radians for internals 150 // Convert to radians for internals
149 rotation = Util.Clamp<float>(rotation, -359f, 359f) / 180f * (float)Math.PI; 151 rotation = Util.Clamp<float>(rotation, -359f, 359f) / 180f * (float)Math.PI;
150 }); 152 });
151 options.Add("rotation-center=", delegate (string v) { 153 options.Add("rotation-center=", delegate(string v)
154 {
152 try 155 try
153 { 156 {
154 rotationCenter = v == null ? Vector3.Zero : Vector3.Parse(v); 157 rotationCenter = v == null ? Vector3.Zero : Vector3.Parse(v);
@@ -288,12 +291,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
288 Dictionary<string, object> archiveOptions = new Dictionary<string, object>(); 291 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
289 DearchiveRegion(loadPath, Guid.Empty, archiveOptions); 292 DearchiveRegion(loadPath, Guid.Empty, archiveOptions);
290 } 293 }
291 294
292 public void DearchiveRegion(string loadPath, Guid requestId, Dictionary<string,object> options) 295 public void DearchiveRegion(string loadPath, Guid requestId, Dictionary<string, object> options)
293 { 296 {
294 m_log.InfoFormat( 297 m_log.InfoFormat(
295 "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath); 298 "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath);
296 299
297 new ArchiveReadRequest(Scene, loadPath, requestId, options).DearchiveRegion(); 300 new ArchiveReadRequest(Scene, loadPath, requestId, options).DearchiveRegion();
298 } 301 }
299 302
@@ -302,7 +305,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
302 Dictionary<string, object> archiveOptions = new Dictionary<string, object>(); 305 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
303 DearchiveRegion(loadStream, Guid.Empty, archiveOptions); 306 DearchiveRegion(loadStream, Guid.Empty, archiveOptions);
304 } 307 }
305
306 public void DearchiveRegion(Stream loadStream, Guid requestId, Dictionary<string, object> options) 308 public void DearchiveRegion(Stream loadStream, Guid requestId, Dictionary<string, object> options)
307 { 309 {
308 new ArchiveReadRequest(Scene, loadStream, requestId, options).DearchiveRegion(); 310 new ArchiveReadRequest(Scene, loadStream, requestId, options).DearchiveRegion();
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index db66c83..895b55d 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 80fa08a..3ded00c 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -68,6 +68,8 @@ namespace OpenSim.Region.CoreModules.World.Estate
68 public event ChangeDelegate OnEstateInfoChange; 68 public event ChangeDelegate OnEstateInfoChange;
69 public event MessageDelegate OnEstateMessage; 69 public event MessageDelegate OnEstateMessage;
70 70
71 private int m_delayCount = 0;
72
71 #region Region Module interface 73 #region Region Module interface
72 74
73 public string Name { get { return "EstateManagementModule"; } } 75 public string Name { get { return "EstateManagementModule"; } }
@@ -95,6 +97,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
95 97
96 m_commands = new EstateManagementCommands(this); 98 m_commands = new EstateManagementCommands(this);
97 m_commands.Initialise(); 99 m_commands.Initialise();
100
101 m_regionChangeTimer.Interval = 10000;
102 m_regionChangeTimer.Elapsed += RaiseRegionInfoChange;
103 m_regionChangeTimer.AutoReset = false;
98 } 104 }
99 105
100 public void RemoveRegion(Scene scene) {} 106 public void RemoveRegion(Scene scene) {}
@@ -142,6 +148,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
142 flags |= RegionFlags.AllowParcelChanges; 148 flags |= RegionFlags.AllowParcelChanges;
143 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch) 149 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch)
144 flags |= RegionFlags.BlockParcelSearch; 150 flags |= RegionFlags.BlockParcelSearch;
151 if (Scene.RegionInfo.RegionSettings.GodBlockSearch)
152 flags |= (RegionFlags)(1 << 11);
153 if (Scene.RegionInfo.RegionSettings.Casino)
154 flags |= (RegionFlags)(1 << 10);
145 155
146 if (Scene.RegionInfo.RegionSettings.FixedSun) 156 if (Scene.RegionInfo.RegionSettings.FixedSun)
147 flags |= RegionFlags.SunFixed; 157 flags |= RegionFlags.SunFixed;
@@ -194,6 +204,14 @@ namespace OpenSim.Region.CoreModules.World.Estate
194 change(Scene.RegionInfo.RegionID); 204 change(Scene.RegionInfo.RegionID);
195 } 205 }
196 206
207 protected void RaiseRegionInfoChange(object sender, ElapsedEventArgs e)
208 {
209 ChangeDelegate change = OnRegionInfoChange;
210
211 if (change != null)
212 change(Scene.RegionInfo.RegionID);
213 }
214
197 public void TriggerRegionInfoChange() 215 public void TriggerRegionInfoChange()
198 { 216 {
199 m_regionChangeTimer.Stop(); 217 m_regionChangeTimer.Stop();
@@ -587,6 +605,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
587 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>(); 605 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>();
588 if (restartModule != null) 606 if (restartModule != null)
589 { 607 {
608 if (timeInSeconds == -1)
609 {
610 m_delayCount++;
611 if (m_delayCount > 3)
612 return;
613
614 restartModule.DelayRestart(3600, "Restart delayed by region manager");
615 return;
616 }
617
590 List<int> times = new List<int>(); 618 List<int> times = new List<int>();
591 while (timeInSeconds > 0) 619 while (timeInSeconds > 0)
592 { 620 {
@@ -1477,7 +1505,8 @@ namespace OpenSim.Region.CoreModules.World.Estate
1477 sendRegionHandshake(client); 1505 sendRegionHandshake(client);
1478 } 1506 }
1479 1507
1480 private uint GetEstateFlags() 1508
1509 public uint GetEstateFlags()
1481 { 1510 {
1482 RegionFlags flags = RegionFlags.None; 1511 RegionFlags flags = RegionFlags.None;
1483 1512
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
index 73c592d..378826d 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
@@ -40,23 +40,33 @@ namespace OpenSim.Region.CoreModules.World.Land
40 //Land types set with flags in ParcelOverlay. 40 //Land types set with flags in ParcelOverlay.
41 //Only one of these can be used. 41 //Only one of these can be used.
42 public const float BAN_LINE_SAFETY_HIEGHT = 100; 42 public const float BAN_LINE_SAFETY_HIEGHT = 100;
43 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = 128; //Equals 10000000
44 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = 64; //Equals 01000000
45 43
46 //RequestResults (I think these are right, they seem to work): 44 //RequestResults (I think these are right, they seem to work):
47 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land 45 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land
48 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land 46 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land
49 47
50 //ParcelSelectObjects 48 //ParcelSelectObjects
49 public const int LAND_SELECT_OBJECTS_OWNER = 2;
51 public const int LAND_SELECT_OBJECTS_GROUP = 4; 50 public const int LAND_SELECT_OBJECTS_GROUP = 4;
52 public const int LAND_SELECT_OBJECTS_OTHER = 8; 51 public const int LAND_SELECT_OBJECTS_OTHER = 8;
53 public const int LAND_SELECT_OBJECTS_OWNER = 2; 52
54 public const byte LAND_TYPE_IS_BEING_AUCTIONED = 5; //Equals 00000101 53
55 public const byte LAND_TYPE_IS_FOR_SALE = 4; //Equals 00000100 54 public const byte LAND_TYPE_PUBLIC = 0; //Equals 00000000
56 public const byte LAND_TYPE_OWNED_BY_GROUP = 2; //Equals 00000010 55 // types 1 to 7 are exclusive
57 public const byte LAND_TYPE_OWNED_BY_OTHER = 1; //Equals 00000001 56 public const byte LAND_TYPE_OWNED_BY_OTHER = 1; //Equals 00000001
57 public const byte LAND_TYPE_OWNED_BY_GROUP = 2; //Equals 00000010
58 public const byte LAND_TYPE_OWNED_BY_REQUESTER = 3; //Equals 00000011 58 public const byte LAND_TYPE_OWNED_BY_REQUESTER = 3; //Equals 00000011
59 public const byte LAND_TYPE_PUBLIC = 0; //Equals 00000000 59 public const byte LAND_TYPE_IS_FOR_SALE = 4; //Equals 00000100
60 public const byte LAND_TYPE_IS_BEING_AUCTIONED = 5; //Equals 00000101
61 public const byte LAND_TYPE_unused6 = 6;
62 public const byte LAND_TYPE_unused7 = 7;
63 // next are flags
64 public const byte LAND_FLAG_unused8 = 0x08; // this may become excluside in future
65 public const byte LAND_FLAG_HIDEAVATARS = 0x10;
66 public const byte LAND_FLAG_LOCALSOUND = 0x20;
67 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = 0x40; //Equals 01000000
68 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = 0x80; //Equals 10000000
69
60 70
61 //These are other constants. Yay! 71 //These are other constants. Yay!
62 public const int START_LAND_LOCAL_ID = 1; 72 public const int START_LAND_LOCAL_ID = 1;
@@ -203,7 +213,13 @@ namespace OpenSim.Region.CoreModules.World.Land
203 m_landManagementModule.setParcelOtherCleanTime(remoteClient, localID, otherCleanTime); 213 m_landManagementModule.setParcelOtherCleanTime(remoteClient, localID, otherCleanTime);
204 } 214 }
205 } 215 }
206 216 public void sendClientInitialLandInfo(IClientAPI remoteClient)
217 {
218 if (m_landManagementModule != null)
219 {
220 m_landManagementModule.sendClientInitialLandInfo(remoteClient);
221 }
222 }
207 #endregion 223 #endregion
208 } 224 }
209} 225}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 92f6c1b..ad6793f 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -69,6 +69,7 @@ namespace OpenSim.Region.CoreModules.World.Land
69 /// <summary> 69 /// <summary>
70 /// Minimum land unit size in region co-ordinates. 70 /// Minimum land unit size in region co-ordinates.
71 /// </summary> 71 /// </summary>
72
72 public const int LandUnit = 4; 73 public const int LandUnit = 4;
73 74
74 private static readonly string remoteParcelRequestPath = "0009/"; 75 private static readonly string remoteParcelRequestPath = "0009/";
@@ -89,21 +90,26 @@ namespace OpenSim.Region.CoreModules.World.Land
89 /// <value> 90 /// <value>
90 /// Land objects keyed by local id 91 /// Land objects keyed by local id
91 /// </value> 92 /// </value>
92 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); 93// private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
94
95 //ubit: removed the readonly so i can move it around
96 private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
93 97
94 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 98 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
95 99
96 private bool m_allowedForcefulBans = true; 100 private bool m_allowedForcefulBans = true;
101 private UUID DefaultGodParcelGroup;
102 private string DefaultGodParcelName;
97 103
98 // caches ExtendedLandData 104 // caches ExtendedLandData
99 private Cache parcelInfoCache; 105 private Cache parcelInfoCache;
100 106
101
102 /// <summary> 107 /// <summary>
103 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. 108 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
104 /// </summary> 109 /// </summary>
105 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); 110 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>();
106 111
112
107 // Enables limiting parcel layer info transmission when doing simple updates 113 // Enables limiting parcel layer info transmission when doing simple updates
108 private bool shouldLimitParcelLayerInfoToViewDistance { get; set; } 114 private bool shouldLimitParcelLayerInfoToViewDistance { get; set; }
109 // "View distance" for sending parcel layer info if asked for from a view point in the region 115 // "View distance" for sending parcel layer info if asked for from a view point in the region
@@ -125,6 +131,8 @@ namespace OpenSim.Region.CoreModules.World.Land
125 { 131 {
126 shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance); 132 shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance);
127 parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance); 133 parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance);
134 DefaultGodParcelGroup = new UUID(landManagementConfig.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
135 DefaultGodParcelName = landManagementConfig.GetString("DefaultAdministratorParcelName", "Default Parcel");
128 } 136 }
129 } 137 }
130 138
@@ -132,6 +140,7 @@ namespace OpenSim.Region.CoreModules.World.Land
132 { 140 {
133 m_scene = scene; 141 m_scene = scene;
134 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; 142 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
143
135 landChannel = new LandChannel(scene, this); 144 landChannel = new LandChannel(scene, this);
136 145
137 parcelInfoCache = new Cache(); 146 parcelInfoCache = new Cache();
@@ -154,7 +163,7 @@ namespace OpenSim.Region.CoreModules.World.Land
154 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; 163 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage;
155 m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan; 164 m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan;
156 m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps; 165 m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps;
157 166
158 lock (m_scene) 167 lock (m_scene)
159 { 168 {
160 m_scene.LandChannel = (ILandChannel)landChannel; 169 m_scene.LandChannel = (ILandChannel)landChannel;
@@ -204,13 +213,14 @@ namespace OpenSim.Region.CoreModules.World.Land
204 client.OnParcelFreezeUser += ClientOnParcelFreezeUser; 213 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
205 client.OnSetStartLocationRequest += ClientOnSetHome; 214 client.OnSetStartLocationRequest += ClientOnSetHome;
206 215
207 216/* avatar is still a child here position is unknown
208 EntityBase presenceEntity; 217 EntityBase presenceEntity;
209 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)
210 { 219 {
211 SendLandUpdate((ScenePresence)presenceEntity, true); 220 SendLandUpdate((ScenePresence)presenceEntity, true);
212 SendParcelOverlay(client); 221 SendParcelOverlay(client);
213 } 222 }
223*/
214 } 224 }
215 225
216 public void EventMakeChildAgent(ScenePresence avatar) 226 public void EventMakeChildAgent(ScenePresence avatar)
@@ -220,48 +230,6 @@ namespace OpenSim.Region.CoreModules.World.Land
220 230
221 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 231 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
222 { 232 {
223 //If we are forcing a position for them to go
224 if (forcedPosition.ContainsKey(remoteClient.AgentId))
225 {
226 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
227
228 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
229 //When the avatar walks into a ban line on the ground, it prevents getting stuck
230 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
231
232 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
233 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
234 {
235// m_log.DebugFormat(
236// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
237// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
238
239 forcedPosition.Remove(remoteClient.AgentId);
240 }
241 //if we are far away, teleport
242 else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
243 {
244 Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
245// m_log.DebugFormat(
246// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
247// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
248
249 m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
250 forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
251
252 forcedPosition.Remove(remoteClient.AgentId);
253 }
254 else
255 {
256// m_log.DebugFormat(
257// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
258// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
259
260 //Forces them toward the forced position we want if they aren't there yet
261 agentData.UseClientAgentPosition = true;
262 agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
263 }
264 }
265 } 233 }
266 234
267 public void Close() 235 public void Close()
@@ -314,6 +282,7 @@ namespace OpenSim.Region.CoreModules.World.Land
314 { 282 {
315 m_landList.Clear(); 283 m_landList.Clear();
316 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 284 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
285
317 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; 286 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
318 } 287 }
319 } 288 }
@@ -324,16 +293,16 @@ namespace OpenSim.Region.CoreModules.World.Land
324 /// <returns>The parcel created.</returns> 293 /// <returns>The parcel created.</returns>
325 protected ILandObject CreateDefaultParcel() 294 protected ILandObject CreateDefaultParcel()
326 { 295 {
327 m_log.DebugFormat( 296 m_log.DebugFormat("{0} Creating default parcel for region {1}", LogHeader, m_scene.RegionInfo.RegionName);
328 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 297
329 298 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
330 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 299
331 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, 300 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
332 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY)); 301 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
333 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 302 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
334 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 303 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
335 304
336 return AddLandObject(fullSimParcel); 305 return AddLandObject(fullSimParcel);
337 } 306 }
338 307
339 public List<ILandObject> AllParcels() 308 public List<ILandObject> AllParcels()
@@ -382,10 +351,17 @@ namespace OpenSim.Region.CoreModules.World.Land
382 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 351 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
383 { 352 {
384 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 353 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
385 if (position.HasValue) 354
386 { 355 if (!position.HasValue)
387 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; 356 return;
388 } 357
358// land should have no word on avatar physics
359// bool isFlying = avatar.PhysicsActor.Flying;
360// avatar.RemoveFromPhysicalScene();
361
362 avatar.AbsolutePosition = (Vector3)position;
363
364// avatar.AddToPhysicalScene(isFlying);
389 } 365 }
390 366
391 public void SendYouAreRestrictedNotice(ScenePresence avatar) 367 public void SendYouAreRestrictedNotice(ScenePresence avatar)
@@ -405,36 +381,14 @@ namespace OpenSim.Region.CoreModules.World.Land
405 } 381 }
406 382
407 if (parcelAvatarIsEntering != null) 383 if (parcelAvatarIsEntering != null)
408 { 384 EnforceBans(parcelAvatarIsEntering, avatar);
409 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
410 {
411 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
412 {
413 SendYouAreBannedNotice(avatar);
414 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
415 }
416 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
417 {
418 SendYouAreRestrictedNotice(avatar);
419 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
420 }
421 else
422 {
423 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
424 }
425 }
426 else
427 {
428 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
429 }
430 }
431 } 385 }
432 } 386 }
433 387
434 public void SendOutNearestBanLine(IClientAPI client) 388 public void SendOutNearestBanLine(IClientAPI client)
435 { 389 {
436 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 390 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
437 if (sp == null || sp.IsChildAgent) 391 if (sp == null)
438 return; 392 return;
439 393
440 List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition); 394 List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition);
@@ -454,32 +408,44 @@ namespace OpenSim.Region.CoreModules.World.Land
454 return; 408 return;
455 } 409 }
456 410
411 public void sendClientInitialLandInfo(IClientAPI remoteClient)
412 {
413 ScenePresence avatar;
414
415 if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out avatar))
416 return;
417
418
419 if (!avatar.IsChildAgent)
420 {
421 ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
422 if (over == null)
423 return;
424
425 avatar.currentParcelUUID = over.LandData.GlobalID;
426 over.SendLandUpdateToClient(avatar.ControllingClient);
427 }
428 SendParcelOverlay(remoteClient);
429 }
430
457 public void SendLandUpdate(ScenePresence avatar, bool force) 431 public void SendLandUpdate(ScenePresence avatar, bool force)
458 { 432 {
459 ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 433 if (avatar.IsChildAgent)
460 (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 434 return;
435
436 ILandObject over = GetLandObjectClipedXY(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
461 437
462 if (over != null) 438 if (over != null)
463 { 439 {
464 if (force) 440 bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID);
465 { 441 if (force || NotsameID)
466 if (!avatar.IsChildAgent)
467 {
468 over.SendLandUpdateToClient(avatar.ControllingClient);
469 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
470 m_scene.RegionInfo.RegionID);
471 }
472 }
473
474 if (avatar.currentParcelUUID != over.LandData.GlobalID)
475 { 442 {
476 if (!avatar.IsChildAgent) 443 over.SendLandUpdateToClient(avatar.ControllingClient);
477 { 444// sl doesnt seem to send this now, as it used 2
478 over.SendLandUpdateToClient(avatar.ControllingClient); 445// SendParcelOverlay(avatar.ControllingClient);
479 avatar.currentParcelUUID = over.LandData.GlobalID; 446 avatar.currentParcelUUID = over.LandData.GlobalID;
480 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, 447 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
481 m_scene.RegionInfo.RegionID); 448 m_scene.RegionInfo.RegionID);
482 }
483 } 449 }
484 } 450 }
485 } 451 }
@@ -531,6 +497,7 @@ namespace OpenSim.Region.CoreModules.World.Land
531 //when we are finally in a safe place, lets release the forced position lock 497 //when we are finally in a safe place, lets release the forced position lock
532 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 498 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
533 } 499 }
500 EnforceBans(parcel, clientAvatar);
534 } 501 }
535 } 502 }
536 503
@@ -589,7 +556,7 @@ namespace OpenSim.Region.CoreModules.World.Land
589 requiredPowers = GroupPowers.LandManageBanned; 556 requiredPowers = GroupPowers.LandManageBanned;
590 557
591 if (m_scene.Permissions.CanEditParcelProperties(agentID, 558 if (m_scene.Permissions.CanEditParcelProperties(agentID,
592 land, requiredPowers)) 559 land, requiredPowers, false))
593 { 560 {
594 land.UpdateAccessList(flags, transactionID, sequenceID, 561 land.UpdateAccessList(flags, transactionID, sequenceID,
595 sections, entries, remote_client); 562 sections, entries, remote_client);
@@ -623,14 +590,11 @@ namespace OpenSim.Region.CoreModules.World.Land
623 new_land.LandData.LocalID = newLandLocalID; 590 new_land.LandData.LocalID = newLandLocalID;
624 591
625 bool[,] landBitmap = new_land.GetLandBitmap(); 592 bool[,] landBitmap = new_land.GetLandBitmap();
626 // m_log.DebugFormat("{0} AddLandObject. new_land.bitmapSize=({1},{2}). newLocalID={3}",
627 // LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), newLandLocalID);
628
629 if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1)) 593 if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
630 { 594 {
631 // Going to variable sized regions can cause mismatches 595 // Going to variable sized regions can cause mismatches
632 m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})", 596 m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})",
633 LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1) ); 597 LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1));
634 } 598 }
635 else 599 else
636 { 600 {
@@ -652,7 +616,7 @@ namespace OpenSim.Region.CoreModules.World.Land
652 { 616 {
653 m_log.ErrorFormat( 617 m_log.ErrorFormat(
654 "{0}: Cannot add parcel \"{1}\", local ID {2} at tile {3},{4} because this is still occupied by parcel \"{5}\", local ID {6} in {7}", 618 "{0}: Cannot add parcel \"{1}\", local ID {2} at tile {3},{4} because this is still occupied by parcel \"{5}\", local ID {6} in {7}",
655 LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y, 619 LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y,
656 lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name); 620 lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name);
657 621
658 return null; 622 return null;
@@ -668,10 +632,10 @@ namespace OpenSim.Region.CoreModules.World.Land
668 { 632 {
669 if (landBitmap[x, y]) 633 if (landBitmap[x, y])
670 { 634 {
671 // m_log.DebugFormat( 635 // m_log.DebugFormat(
672 // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", 636 // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
673 // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName); 637 // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
674 638
675 m_landIDList[x, y] = newLandLocalID; 639 m_landIDList[x, y] = newLandLocalID;
676 } 640 }
677 } 641 }
@@ -723,27 +687,28 @@ namespace OpenSim.Region.CoreModules.World.Land
723 /// </summary> 687 /// </summary>
724 public void Clear(bool setupDefaultParcel) 688 public void Clear(bool setupDefaultParcel)
725 { 689 {
726 List<ILandObject> parcels; 690 Dictionary<int, ILandObject> landworkList;
691 // move to work pointer since we are deleting it all
727 lock (m_landList) 692 lock (m_landList)
728 { 693 {
729 parcels = new List<ILandObject>(m_landList.Values); 694 landworkList = m_landList;
695 m_landList = new Dictionary<int, ILandObject>();
730 } 696 }
731 697
732 foreach (ILandObject lo in parcels) 698 // this 2 methods have locks (now)
699 ResetSimLandObjects();
700
701 if (setupDefaultParcel)
702 CreateDefaultParcel();
703
704 // fire outside events unlocked
705 foreach (ILandObject lo in landworkList.Values)
733 { 706 {
734 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 707 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
735 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); 708 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
736 } 709 }
710 landworkList.Clear();
737 711
738 lock (m_landList)
739 {
740 m_landList.Clear();
741
742 ResetSimLandObjects();
743 }
744
745 if (setupDefaultParcel)
746 CreateDefaultParcel();
747 } 712 }
748 713
749 private void performFinalLandJoin(ILandObject master, ILandObject slave) 714 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -787,58 +752,37 @@ namespace OpenSim.Region.CoreModules.World.Land
787 /// <returns>Land object at the point supplied</returns> 752 /// <returns>Land object at the point supplied</returns>
788 public ILandObject GetLandObject(float x_float, float y_float) 753 public ILandObject GetLandObject(float x_float, float y_float)
789 { 754 {
790 return GetLandObject((int)x_float, (int)y_float, true /* returnNullIfLandObjectNotFound */); 755 return GetLandObject((int)x_float, (int)y_float, true);
791 /* 756 }
792 int x;
793 int y;
794
795 if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0)
796 return null;
797 757
798 try 758 // if x,y is off region this will return the parcel at cliped x,y
799 { 759 // as did code it replaces
800 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit)); 760 public ILandObject GetLandObjectClipedXY(float x, float y)
801 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit)); 761 {
802 } 762 //do clip inline
803 catch (OverflowException) 763 int avx = (int)x;
804 { 764 if (avx < 0)
805 return null; 765 avx = 0;
806 } 766 else if (avx >= m_scene.RegionInfo.RegionSizeX)
767 avx = (int)Constants.RegionSize - 1;
807 768
808 if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit) 769 int avy = (int)y;
809 || y >= (m_scene.RegionInfo.RegionSizeY / landUnit) 770 if (avy < 0)
810 || x < 0 771 avy = 0;
811 || y < 0) 772 else if (avy >= m_scene.RegionInfo.RegionSizeY)
812 { 773 avy = (int)Constants.RegionSize - 1;
813 return null;
814 }
815 774
816 lock (m_landList) 775 lock (m_landIDList)
817 { 776 {
818 // Corner case. If an autoreturn happens during sim startup
819 // we will come here with the list uninitialized
820 //
821// int landId = m_landIDList[x, y];
822
823// if (landId == 0)
824// m_log.DebugFormat(
825// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
826// x, y, m_scene.RegionInfo.RegionName);
827
828 try 777 try
829 { 778 {
830 if (m_landList.ContainsKey(m_landIDList[x, y])) 779 return m_landList[m_landIDList[avx / LandUnit, avy / LandUnit]];
831 return m_landList[m_landIDList[x, y]];
832 } 780 }
833 catch (Exception e) 781 catch (IndexOutOfRangeException)
834 { 782 {
835 m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})", 783 return null;
836 LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
837 } 784 }
838
839 return null;
840 } 785 }
841 */
842 } 786 }
843 787
844 // Public entry. 788 // Public entry.
@@ -848,30 +792,28 @@ namespace OpenSim.Region.CoreModules.World.Land
848 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */); 792 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */);
849 } 793 }
850 794
851 /// <summary> 795 public ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds)
852 /// Given a region position, return the parcel land object for that location
853 /// </summary>
854 /// <returns>
855 /// The land object.
856 /// </returns>
857 /// <param name='x'></param>
858 /// <param name='y'></param>
859 /// <param name='returnNullIfLandObjectNotFound'>
860 /// Return null if the land object requested is not within the region's bounds.
861 /// </param>
862 private ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds)
863 { 796 {
864 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0) 797 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
865 { 798 {
866 // These exceptions here will cause a lot of complaints from the users specifically because 799 // These exceptions here will cause a lot of complaints from the users specifically because
867 // they happen every time at border crossings 800 // they happen every time at border crossings
868 if (returnNullIfLandObjectOutsideBounds) 801 if (returnNullIfLandObjectOutsideBounds)
869 return null; 802 return null;
870 else 803 else
871 throw new Exception( 804 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
872 String.Format("{0} GetLandObject for non-existent position. Region={1}, pos=<{2},{3}", 805 }
873 LogHeader, m_scene.RegionInfo.RegionName, x, y) 806
874 ); 807 lock (m_landIDList)
808 {
809 try
810 {
811 return m_landList[m_landIDList[x / 4, y / 4]];
812 }
813 catch (IndexOutOfRangeException)
814 {
815 return null;
816 }
875 } 817 }
876 818
877 return m_landList[m_landIDList[x / 4, y / 4]]; 819 return m_landList[m_landIDList[x / 4, y / 4]];
@@ -1033,7 +975,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1033 975
1034 //If we are still here, then they are subdividing within one piece of land 976 //If we are still here, then they are subdividing within one piece of land
1035 //Check owner 977 //Check owner
1036 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin)) 978 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin, true))
1037 { 979 {
1038 return; 980 return;
1039 } 981 }
@@ -1043,6 +985,8 @@ namespace OpenSim.Region.CoreModules.World.Land
1043 newLand.LandData.Name = newLand.LandData.Name; 985 newLand.LandData.Name = newLand.LandData.Name;
1044 newLand.LandData.GlobalID = UUID.Random(); 986 newLand.LandData.GlobalID = UUID.Random();
1045 newLand.LandData.Dwell = 0; 987 newLand.LandData.Dwell = 0;
988 // Clear "Show in search" on the cut out parcel to prevent double-charging
989 newLand.LandData.Flags &= ~(uint)ParcelFlags.ShowDirectory;
1046 990
1047 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y)); 991 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y));
1048 992
@@ -1058,11 +1002,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1058 //Now add the new land object 1002 //Now add the new land object
1059 ILandObject result = AddLandObject(newLand); 1003 ILandObject result = AddLandObject(newLand);
1060 1004
1061 if (result != null) 1005 UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData);
1062 { 1006 result.SendLandUpdateToAvatarsOverMe();
1063 UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); 1007 startLandObject.SendLandUpdateToAvatarsOverMe();
1064 result.SendLandUpdateToAvatarsOverMe(); 1008 m_scene.ForEachClient(SendParcelOverlay);
1065 } 1009
1066 } 1010 }
1067 1011
1068 /// <summary> 1012 /// <summary>
@@ -1104,7 +1048,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1104 { 1048 {
1105 return; 1049 return;
1106 } 1050 }
1107 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin)) 1051 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin, true))
1108 { 1052 {
1109 return; 1053 return;
1110 } 1054 }
@@ -1127,6 +1071,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1127 } 1071 }
1128 1072
1129 masterLandObject.SendLandUpdateToAvatarsOverMe(); 1073 masterLandObject.SendLandUpdateToAvatarsOverMe();
1074 m_scene.ForEachClient(SendParcelOverlay);
1130 } 1075 }
1131 1076
1132 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) 1077 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
@@ -1143,12 +1088,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1143 1088
1144 #region Parcel Updating 1089 #region Parcel Updating
1145 1090
1146 // Send parcel layer info for the whole region
1147 public void SendParcelOverlay(IClientAPI remote_client)
1148 {
1149 SendParcelOverlay(remote_client, 0, 0, (int)Constants.MaximumRegionSize);
1150 }
1151
1152 /// <summary> 1091 /// <summary>
1153 /// Send the parcel overlay blocks to the client. We send the overlay packets 1092 /// Send the parcel overlay blocks to the client. We send the overlay packets
1154 /// around a location and limited by the 'parcelLayerViewDistance'. This number 1093 /// around a location and limited by the 'parcelLayerViewDistance'. This number
@@ -1162,145 +1101,116 @@ namespace OpenSim.Region.CoreModules.World.Land
1162 /// <param name="xPlace">X position in the region to send surrounding parcel layer info</param> 1101 /// <param name="xPlace">X position in the region to send surrounding parcel layer info</param>
1163 /// <param name="yPlace">y position in the region to send surrounding parcel layer info</param> 1102 /// <param name="yPlace">y position in the region to send surrounding parcel layer info</param>
1164 /// <param name="layerViewDistance">Distance from x,y position to send parcel layer info</param> 1103 /// <param name="layerViewDistance">Distance from x,y position to send parcel layer info</param>
1165 private void SendParcelOverlay(IClientAPI remote_client, int xPlace, int yPlace, int layerViewDistance) 1104 public void SendParcelOverlay(IClientAPI remote_client)
1166 { 1105 {
1106 if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
1107 return;
1108
1167 const int LAND_BLOCKS_PER_PACKET = 1024; 1109 const int LAND_BLOCKS_PER_PACKET = 1024;
1168 1110
1169 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1111 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1170 int byteArrayCount = 0; 1112 int byteArrayCount = 0;
1171 int sequenceID = 0; 1113 int sequenceID = 0;
1172 1114
1173 int xLow = 0; 1115 // Layer data is in LandUnit (4m) chunks
1174 int xHigh = (int)m_scene.RegionInfo.RegionSizeX; 1116 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y += LandUnit)
1175 int yLow = 0;
1176 int yHigh = (int)m_scene.RegionInfo.RegionSizeY;
1177
1178 if (shouldLimitParcelLayerInfoToViewDistance)
1179 { 1117 {
1180 // Compute view distance around the given point 1118 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x += LandUnit)
1181 int txLow = xPlace - layerViewDistance;
1182 int txHigh = xPlace + layerViewDistance;
1183 // If the distance is outside the region area, move the view distance to ba all in the region
1184 if (txLow < xLow)
1185 {
1186 txLow = xLow;
1187 txHigh = Math.Min(yLow + (layerViewDistance * 2), xHigh);
1188 }
1189 if (txHigh > xHigh)
1190 { 1119 {
1191 txLow = Math.Max(xLow, xHigh - (layerViewDistance * 2)); 1120 byte tempByte = 0; //This represents the byte for the current 4x4
1192 txHigh = xHigh;
1193 }
1194 xLow = txLow;
1195 xHigh = txHigh;
1196 1121
1197 int tyLow = yPlace - layerViewDistance; 1122 ILandObject currentParcelBlock = GetLandObject(x, y);
1198 int tyHigh = yPlace + layerViewDistance;
1199 if (tyLow < yLow)
1200 {
1201 tyLow = yLow;
1202 tyHigh = Math.Min(yLow + (layerViewDistance * 2), yHigh);
1203 }
1204 if (tyHigh > yHigh)
1205 {
1206 tyLow = Math.Max(yLow, yHigh - (layerViewDistance * 2));
1207 tyHigh = yHigh;
1208 }
1209 yLow = tyLow;
1210 yHigh = tyHigh;
1211 }
1212 // m_log.DebugFormat("{0} SendParcelOverlay: place=<{1},{2}>, vDist={3}, xLH=<{4},{5}, yLH=<{6},{7}>",
1213 // LogHeader, xPlace, yPlace, layerViewDistance, xLow, xHigh, yLow, yHigh);
1214 1123
1215 // Layer data is in landUnit (4m) chunks 1124 if (currentParcelBlock != null)
1216 for (int y = yLow; y < yHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
1217 {
1218 for (int x = xLow; x < xHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
1219 {
1220 byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * LandUnit, y * LandUnit), x, y, remote_client);
1221 byteArrayCount++;
1222 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
1223 { 1125 {
1224 // m_log.DebugFormat("{0} SendParcelOverlay, sending packet, bytes={1}", LogHeader, byteArray.Length); 1126 // types
1225 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1127 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
1226 byteArrayCount = 0; 1128 {
1227 sequenceID++; 1129 //Owner Flag
1228 byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1130 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
1229 } 1131 }
1132 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1133 {
1134 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_GROUP;
1135 }
1136 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1137 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1138 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1139 {
1140 //Sale type
1141 tempByte = (byte)LandChannel.LAND_TYPE_IS_FOR_SALE;
1142 }
1143 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1144 {
1145 //Public type
1146 tempByte = (byte)LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero
1147 }
1148 // LAND_TYPE_IS_BEING_AUCTIONED still unsuported
1149 else
1150 {
1151 //Other Flag
1152 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_OTHER;
1153 }
1230 1154
1231 } 1155 // now flags
1232 } 1156 // border control
1233 1157
1234 if (byteArrayCount != 0) 1158 ILandObject westParcel = null;
1235 { 1159 ILandObject southParcel = null;
1236 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1160 if (x > 0)
1237 // m_log.DebugFormat("{0} SendParcelOverlay, complete sending packet, bytes={1}", LogHeader, byteArray.Length); 1161 {
1238 } 1162 westParcel = GetLandObject((x - 1), y);
1239 } 1163 }
1164 if (y > 0)
1165 {
1166 southParcel = GetLandObject(x, (y - 1));
1167 }
1240 1168
1241 private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client) 1169 if (x == 0)
1242 { 1170 {
1243 byte tempByte = 0; //This represents the byte for the current 4x4 1171 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
1172 }
1173 else if (westParcel != null && westParcel != currentParcelBlock)
1174 {
1175 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
1176 }
1244 1177
1245 if (currentParcelBlock != null) 1178 if (y == 0)
1246 { 1179 {
1247 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) 1180 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
1248 { 1181 }
1249 //Owner Flag 1182 else if (southParcel != null && southParcel != currentParcelBlock)
1250 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1183 {
1251 } 1184 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
1252 else if (currentParcelBlock.LandData.SalePrice > 0 && 1185 }
1253 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1254 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1255 {
1256 //Sale Flag
1257 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
1258 }
1259 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1260 {
1261 //Public Flag
1262 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
1263 }
1264 else
1265 {
1266 //Other Flag
1267 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
1268 }
1269 1186
1270 //Now for border control 1187 // local sound
1188 if ((currentParcelBlock.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
1189 tempByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
1271 1190
1272 ILandObject westParcel = null; 1191 // hide avatars
1273 ILandObject southParcel = null; 1192 if (!currentParcelBlock.LandData.SeeAVs)
1274 if (x > 0) 1193 tempByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS;
1275 {
1276 westParcel = GetLandObject((x - 1) * LandUnit, y * LandUnit);
1277 }
1278 if (y > 0)
1279 {
1280 southParcel = GetLandObject(x * LandUnit, (y - 1) * LandUnit);
1281 }
1282 1194
1283 if (x == 0)
1284 {
1285 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1286 }
1287 else if (westParcel != null && westParcel != currentParcelBlock)
1288 {
1289 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1290 }
1291 1195
1292 if (y == 0) 1196 byteArray[byteArrayCount] = tempByte;
1293 { 1197 byteArrayCount++;
1294 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1198 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
1295 } 1199 {
1296 else if (southParcel != null && southParcel != currentParcelBlock) 1200 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1297 { 1201 byteArrayCount = 0;
1298 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1202 sequenceID++;
1203 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1204 }
1205 }
1299 } 1206 }
1300 1207
1301 } 1208 }
1302 1209
1303 return tempByte; 1210 if (byteArrayCount > 0)
1211 {
1212 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1213 }
1304 } 1214 }
1305 1215
1306 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, 1216 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
@@ -1320,8 +1230,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1320 { 1230 {
1321 if (!temp.Contains(currentParcel)) 1231 if (!temp.Contains(currentParcel))
1322 { 1232 {
1323 currentParcel.ForceUpdateLandInfo(); 1233 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId))
1324 temp.Add(currentParcel); 1234 {
1235 currentParcel.ForceUpdateLandInfo();
1236 temp.Add(currentParcel);
1237 }
1325 } 1238 }
1326 } 1239 }
1327 } 1240 }
@@ -1338,8 +1251,45 @@ namespace OpenSim.Region.CoreModules.World.Land
1338 temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client); 1251 temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client);
1339 } 1252 }
1340 1253
1341 // Also send the layer data around the point of interest 1254// SendParcelOverlay(remote_client);
1342 SendParcelOverlay(remote_client, (start_x + end_x) / 2, (start_y + end_y) / 2, parcelLayerViewDistance); 1255 }
1256
1257 public void UpdateLandProperties(ILandObject land, LandUpdateArgs args, IClientAPI remote_client)
1258 {
1259 bool snap_selection = false;
1260 bool needOverlay = false;
1261 if (land.UpdateLandProperties(args, remote_client, out snap_selection, out needOverlay))
1262 {
1263 //the proprieties to who changed them
1264 ScenePresence av = m_scene.GetScenePresence(remote_client.AgentId);
1265 if(av.IsChildAgent || land != GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y))
1266 land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, remote_client);
1267 else
1268 land.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, remote_client);
1269
1270 UUID parcelID = land.LandData.GlobalID;
1271 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
1272 {
1273 if (avatar.IsDeleted || avatar.isNPC)
1274 return;
1275
1276 IClientAPI client = avatar.ControllingClient;
1277 if (needOverlay)
1278 SendParcelOverlay(client);
1279
1280 if (avatar.IsChildAgent)
1281 return;
1282
1283 ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
1284 if (aland != null)
1285 {
1286 if (client != remote_client && land == aland)
1287 aland.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, client);
1288 }
1289 if (avatar.currentParcelUUID == parcelID)
1290 avatar.currentParcelUUID = parcelID; // force parcel flags review
1291 });
1292 }
1343 } 1293 }
1344 1294
1345 public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) 1295 public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client)
@@ -1352,7 +1302,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1352 1302
1353 if (land != null) 1303 if (land != null)
1354 { 1304 {
1355 land.UpdateLandProperties(args, remote_client); 1305 UpdateLandProperties(land, args, remote_client);
1356 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client); 1306 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client);
1357 } 1307 }
1358 } 1308 }
@@ -1408,7 +1358,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1408 land.LandData.GroupID = UUID.Zero; 1358 land.LandData.GroupID = UUID.Zero;
1409 land.LandData.IsGroupOwned = false; 1359 land.LandData.IsGroupOwned = false;
1410 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1360 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1411
1412 m_scene.ForEachClient(SendParcelOverlay); 1361 m_scene.ForEachClient(SendParcelOverlay);
1413 land.SendLandUpdateToClient(true, remote_client); 1362 land.SendLandUpdateToClient(true, remote_client);
1414 UpdateLandObject(land.LandData.LocalID, land.LandData); 1363 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1459,7 +1408,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1459 land.LandData.SalePrice = 0; 1408 land.LandData.SalePrice = 0;
1460 land.LandData.AuthBuyerID = UUID.Zero; 1409 land.LandData.AuthBuyerID = UUID.Zero;
1461 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1410 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1462
1463 m_scene.ForEachClient(SendParcelOverlay); 1411 m_scene.ForEachClient(SendParcelOverlay);
1464 land.SendLandUpdateToClient(true, remote_client); 1412 land.SendLandUpdateToClient(true, remote_client);
1465 UpdateLandObject(land.LandData.LocalID, land.LandData); 1413 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1545,17 +1493,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1545 1493
1546 private void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1494 private void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1547 { 1495 {
1548// m_log.DebugFormat(
1549// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name);
1550
1551 // Prevent race conditions from any auto-creation of new parcels for varregions whilst we are still loading
1552 // the existing parcels.
1553 lock (m_landList) 1496 lock (m_landList)
1554 { 1497 {
1555 for (int i = 0; i < data.Count; i++) 1498 for (int i = 0; i < data.Count; i++)
1556 IncomingLandObjectFromStorage(data[i]); 1499 IncomingLandObjectFromStorage(data[i]);
1557 1500
1558 // Layer data is in landUnit (4m) chunks 1501 // Layer data is in LandUnit (4m) chunks
1559 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++) 1502 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
1560 { 1503 {
1561 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++) 1504 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
@@ -1565,7 +1508,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1565 if (m_landList.Count == 1) 1508 if (m_landList.Count == 1)
1566 { 1509 {
1567 m_log.DebugFormat( 1510 m_log.DebugFormat(
1568 "[{0}]: Auto-extending land parcel as landID at {1},{2} is 0 and only one land parcel is present in {3}", 1511 "[{0}]: Auto-extending land parcel as landID at {1},{2} is 0 and only one land parcel is present in {3}",
1569 LogHeader, x, y, m_scene.Name); 1512 LogHeader, x, y, m_scene.Name);
1570 1513
1571 int onlyParcelID = 0; 1514 int onlyParcelID = 0;
@@ -1588,11 +1531,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1588 else if (m_landList.Count > 1) 1531 else if (m_landList.Count > 1)
1589 { 1532 {
1590 m_log.DebugFormat( 1533 m_log.DebugFormat(
1591 "{0}: Auto-creating land parcel as landID at {1},{2} is 0 and more than one land parcel is present in {3}", 1534 "{0}: Auto-creating land parcel as landID at {1},{2} is 0 and more than one land parcel is present in {3}",
1592 LogHeader, x, y, m_scene.Name); 1535 LogHeader, x, y, m_scene.Name);
1593 1536
1594 // There are several other parcels so we must create a new one for the unassigned space 1537 // There are several other parcels so we must create a new one for the unassigned space
1595 ILandObject newLand = new LandObject(UUID.Zero, false, m_scene); 1538 ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
1596 // Claim all the unclaimed "0" ids 1539 // Claim all the unclaimed "0" ids
1597 newLand.SetLandBitmap(CreateBitmapForID(0)); 1540 newLand.SetLandBitmap(CreateBitmapForID(0));
1598 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 1541 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@@ -1603,7 +1546,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1603 { 1546 {
1604 // We should never reach this point as the separate code path when no land data exists should have fired instead. 1547 // We should never reach this point as the separate code path when no land data exists should have fired instead.
1605 m_log.WarnFormat( 1548 m_log.WarnFormat(
1606 "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present", 1549 "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present",
1607 LogHeader, m_scene.Name); 1550 LogHeader, m_scene.Name);
1608 } 1551 }
1609 } 1552 }
@@ -1614,9 +1557,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1614 1557
1615 private void IncomingLandObjectFromStorage(LandData data) 1558 private void IncomingLandObjectFromStorage(LandData data)
1616 { 1559 {
1617 ILandObject new_land = new LandObject(data, m_scene); 1560 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
1561 new_land.LandData = data.Copy();
1562
1618 new_land.SetLandBitmapFromByteArray(); 1563 new_land.SetLandBitmapFromByteArray();
1619 AddLandObject(new_land); 1564 AddLandObject(new_land);
1565// new_land.SendLandUpdateToAvatarsOverMe();
1620 } 1566 }
1621 1567
1622 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1568 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1773,6 +1719,19 @@ namespace OpenSim.Region.CoreModules.World.Land
1773 land_update.ObscureMusic = properties.ObscureMusic; 1719 land_update.ObscureMusic = properties.ObscureMusic;
1774 land_update.ObscureMedia = properties.ObscureMedia; 1720 land_update.ObscureMedia = properties.ObscureMedia;
1775 1721
1722 if (args.ContainsKey("see_avs"))
1723 {
1724 land_update.SeeAVs = args["see_avs"].AsBoolean();
1725 land_update.AnyAVSounds = args["any_av_sounds"].AsBoolean();
1726 land_update.GroupAVSounds = args["group_av_sounds"].AsBoolean();
1727 }
1728 else
1729 {
1730 land_update.SeeAVs = true;
1731 land_update.AnyAVSounds = true;
1732 land_update.GroupAVSounds = true;
1733 }
1734
1776 ILandObject land; 1735 ILandObject land;
1777 lock (m_landList) 1736 lock (m_landList)
1778 { 1737 {
@@ -1781,13 +1740,14 @@ namespace OpenSim.Region.CoreModules.World.Land
1781 1740
1782 if (land != null) 1741 if (land != null)
1783 { 1742 {
1784 land.UpdateLandProperties(land_update, client); 1743 UpdateLandProperties(land,land_update, client);
1785 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client); 1744 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client);
1786 } 1745 }
1787 else 1746 else
1788 { 1747 {
1789 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID); 1748 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID);
1790 } 1749 }
1750
1791 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); 1751 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
1792 } 1752 }
1793 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the 1753 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the
@@ -1940,14 +1900,93 @@ namespace OpenSim.Region.CoreModules.World.Land
1940 1900
1941 if (land == null) return; 1901 if (land == null) return;
1942 1902
1943 if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions)) 1903 if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions, false))
1944 return; 1904 return;
1945 1905
1946 land.LandData.OtherCleanTime = otherCleanTime; 1906 land.LandData.OtherCleanTime = otherCleanTime;
1947 1907
1948 UpdateLandObject(localID, land.LandData); 1908 UpdateLandObject(localID, land.LandData);
1949 } 1909 }
1950 1910
1911 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
1912 {
1913 ILandObject land = null;
1914 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
1915 foreach (ILandObject landObject in Land)
1916 {
1917 if (landObject.LandData.LocalID == landID)
1918 {
1919 land = landObject;
1920 }
1921 }
1922 land.DeedToGroup(DefaultGodParcelGroup);
1923 land.LandData.Name = DefaultGodParcelName;
1924 land.SendLandUpdateToAvatarsOverMe();
1925 }
1926
1927 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
1928 {
1929 ScenePresence SP;
1930 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
1931 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
1932 if (SP.UserLevel != 0)
1933 {
1934 if (flags == 0) //All parcels, scripted or not
1935 {
1936 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1937 {
1938 if (e.OwnerID == targetID)
1939 {
1940 returns.Add(e);
1941 }
1942 }
1943 );
1944 }
1945 if (flags == 4) //All parcels, scripted object
1946 {
1947 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1948 {
1949 if (e.OwnerID == targetID)
1950 {
1951 if (e.ContainsScripts())
1952 {
1953 returns.Add(e);
1954 }
1955 }
1956 }
1957 );
1958 }
1959 if (flags == 4) //not target parcel, scripted object
1960 {
1961 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1962 {
1963 if (e.OwnerID == targetID)
1964 {
1965 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
1966 if (landobject.LandData.OwnerID != e.OwnerID)
1967 {
1968 if (e.ContainsScripts())
1969 {
1970 returns.Add(e);
1971 }
1972 }
1973 }
1974 }
1975 );
1976 }
1977 foreach (SceneObjectGroup ol in returns)
1978 {
1979 ReturnObject(ol, client);
1980 }
1981 }
1982 }
1983 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
1984 {
1985 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1986 objs[0] = obj;
1987 ((Scene)client.Scene).returnObjects(objs, client.AgentId);
1988 }
1989
1951 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); 1990 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1952 1991
1953 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 1992 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
@@ -1961,7 +2000,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1961 if (targetAvatar.UserLevel == 0) 2000 if (targetAvatar.UserLevel == 0)
1962 { 2001 {
1963 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); 2002 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1964 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze)) 2003 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true))
1965 return; 2004 return;
1966 if (flags == 0) 2005 if (flags == 0)
1967 { 2006 {
@@ -1983,7 +2022,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1983 } 2022 }
1984 } 2023 }
1985 } 2024 }
1986
1987 private void OnEndParcelFrozen(object avatar) 2025 private void OnEndParcelFrozen(object avatar)
1988 { 2026 {
1989 ScenePresence targetAvatar = (ScenePresence)avatar; 2027 ScenePresence targetAvatar = (ScenePresence)avatar;
@@ -1994,6 +2032,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1994 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); 2032 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
1995 } 2033 }
1996 2034
2035
1997 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 2036 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1998 { 2037 {
1999 ScenePresence targetAvatar = null; 2038 ScenePresence targetAvatar = null;
@@ -2010,15 +2049,16 @@ namespace OpenSim.Region.CoreModules.World.Land
2010 2049
2011 // Check if you even have permission to do this 2050 // Check if you even have permission to do this
2012 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); 2051 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
2013 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && 2052 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true) &&
2014 !m_scene.Permissions.IsAdministrator(client.AgentId)) 2053 !m_scene.Permissions.IsAdministrator(client.AgentId))
2015 return; 2054 return;
2055
2016 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); 2056 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
2017 2057
2018 targetAvatar.TeleportWithMomentum(pos, null); 2058 targetAvatar.TeleportWithMomentum(pos, null);
2019 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); 2059 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
2020 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); 2060 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
2021 2061
2022 if ((flags & 1) != 0) // Ban TODO: Remove magic number 2062 if ((flags & 1) != 0) // Ban TODO: Remove magic number
2023 { 2063 {
2024 LandAccessEntry entry = new LandAccessEntry(); 2064 LandAccessEntry entry = new LandAccessEntry();
@@ -2171,37 +2211,50 @@ namespace OpenSim.Region.CoreModules.World.Land
2171 2211
2172 private void AppendParcelsSummaryReport(StringBuilder report) 2212 private void AppendParcelsSummaryReport(StringBuilder report)
2173 { 2213 {
2174 report.AppendFormat("Land information for {0}\n", m_scene.Name); 2214 report.AppendFormat("Land information for {0}\n", m_scene.RegionInfo.RegionName);
2175 2215 report.AppendFormat(
2176 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 2216 "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n",
2177 cdt.AddColumn("Parcel Name", ConsoleDisplayUtil.ParcelNameSize); 2217 "Parcel Name",
2178 cdt.AddColumn("ID", 3); 2218 "Local ID",
2179 cdt.AddColumn("Area", 6); 2219 "Area",
2180 cdt.AddColumn("Starts", ConsoleDisplayUtil.VectorSize); 2220 "AABBMin",
2181 cdt.AddColumn("Ends", ConsoleDisplayUtil.VectorSize); 2221 "AABBMax",
2182 cdt.AddColumn("Owner", ConsoleDisplayUtil.UserNameSize); 2222 "Owner");
2183 2223
2184 lock (m_landList) 2224 lock (m_landList)
2185 { 2225 {
2186 foreach (ILandObject lo in m_landList.Values) 2226 foreach (ILandObject lo in m_landList.Values)
2187 { 2227 {
2188 LandData ld = lo.LandData; 2228 LandData ld = lo.LandData;
2189 string ownerName; 2229
2190 if (ld.IsGroupOwned) 2230 report.AppendFormat(
2191 { 2231 "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n",
2192 GroupRecord rec = m_groupManager.GetGroupRecord(ld.GroupID); 2232 ld.Name, ld.LocalID, ld.Area, ld.AABBMin, ld.AABBMax, m_userManager.GetUserName(ld.OwnerID));
2193 ownerName = (rec != null) ? rec.GroupName : "Unknown Group";
2194 }
2195 else
2196 {
2197 ownerName = m_userManager.GetUserName(ld.OwnerID);
2198 }
2199 cdt.AddRow(
2200 ld.Name, ld.LocalID, ld.Area, lo.StartPoint, lo.EndPoint, ownerName);
2201 } 2233 }
2202 } 2234 }
2235
2236 }
2237
2238 public void EnforceBans(ILandObject land, ScenePresence avatar)
2239 {
2240 if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT)
2241 return;
2203 2242
2204 report.Append(cdt.ToString()); 2243 if (land.IsEitherBannedOrRestricted(avatar.UUID))
2244 {
2245 if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y)))
2246 {
2247 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
2248 if (pos == null)
2249 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
2250 else
2251 ForceAvatarToPosition(avatar, (Vector3)pos);
2252 }
2253 else
2254 {
2255 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
2256 }
2257 }
2205 } 2258 }
2206 2259
2207 private void AppendParcelReport(StringBuilder report, ILandObject lo) 2260 private void AppendParcelReport(StringBuilder report, ILandObject lo)
@@ -2214,8 +2267,6 @@ namespace OpenSim.Region.CoreModules.World.Land
2214 cdl.AddRow("Description", ld.Description); 2267 cdl.AddRow("Description", ld.Description);
2215 cdl.AddRow("Snapshot ID", ld.SnapshotID); 2268 cdl.AddRow("Snapshot ID", ld.SnapshotID);
2216 cdl.AddRow("Area", ld.Area); 2269 cdl.AddRow("Area", ld.Area);
2217 cdl.AddRow("Starts", lo.StartPoint);
2218 cdl.AddRow("Ends", lo.EndPoint);
2219 cdl.AddRow("AABB Min", ld.AABBMin); 2270 cdl.AddRow("AABB Min", ld.AABBMin);
2220 cdl.AddRow("AABB Max", ld.AABBMax); 2271 cdl.AddRow("AABB Max", ld.AABBMax);
2221 string ownerName; 2272 string ownerName;
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index a0c1b9d..040c90b 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -50,7 +50,8 @@ namespace OpenSim.Region.CoreModules.World.Land
50 private readonly int landUnit = 4; 50 private readonly int landUnit = 4;
51 51
52 private int m_lastSeqId = 0; 52 private int m_lastSeqId = 0;
53 53 private int m_expiryCounter = 0;
54
54 protected Scene m_scene; 55 protected Scene m_scene;
55 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); 56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
56 protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); 57 protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
@@ -58,7 +59,12 @@ namespace OpenSim.Region.CoreModules.World.Land
58 protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>(); 59 protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>();
59 protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds 60 protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds
60 61
61 public bool[,] LandBitmap { get; set; } 62 private bool[,] m_landBitmap;
63 public bool[,] LandBitmap
64 {
65 get { return m_landBitmap; }
66 set { m_landBitmap = value; }
67 }
62 68
63 #endregion 69 #endregion
64 70
@@ -69,7 +75,13 @@ namespace OpenSim.Region.CoreModules.World.Land
69 return free; 75 return free;
70 } 76 }
71 77
72 public LandData LandData { get; set; } 78 protected LandData m_landData;
79 public LandData LandData
80 {
81 get { return m_landData; }
82
83 set { m_landData = value; }
84 }
73 85
74 public IPrimCounts PrimCounts { get; set; } 86 public IPrimCounts PrimCounts { get; set; }
75 87
@@ -141,6 +153,8 @@ namespace OpenSim.Region.CoreModules.World.Land
141 else 153 else
142 LandData.GroupID = UUID.Zero; 154 LandData.GroupID = UUID.Zero;
143 LandData.IsGroupOwned = is_group_owned; 155 LandData.IsGroupOwned = is_group_owned;
156
157 m_scene.EventManager.OnFrame += OnFrame;
144 } 158 }
145 159
146 #endregion 160 #endregion
@@ -195,10 +209,27 @@ namespace OpenSim.Region.CoreModules.World.Land
195 else 209 else
196 { 210 {
197 // Normal Calculations 211 // Normal Calculations
198 int parcelMax = (int)(((float)LandData.Area / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)) 212 int parcelMax = (int)( (long)LandData.Area
199 * (float)m_scene.RegionInfo.ObjectCapacity 213 * (long)m_scene.RegionInfo.ObjectCapacity
200 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 214 * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus
201 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! 215 / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) );
216 //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax);
217 return parcelMax;
218 }
219 }
220
221 private int GetParcelBasePrimCount()
222 {
223 if (overrideParcelMaxPrimCount != null)
224 {
225 return overrideParcelMaxPrimCount(this);
226 }
227 else
228 {
229 // Normal Calculations
230 int parcelMax = (int)((long)LandData.Area
231 * (long)m_scene.RegionInfo.ObjectCapacity
232 / 65536L);
202 return parcelMax; 233 return parcelMax;
203 } 234 }
204 } 235 }
@@ -212,8 +243,10 @@ namespace OpenSim.Region.CoreModules.World.Land
212 else 243 else
213 { 244 {
214 //Normal Calculations 245 //Normal Calculations
215 int simMax = (int)(((float)LandData.SimwideArea / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)) 246 int simMax = (int)( (long)LandData.SimwideArea
216 * (float)m_scene.RegionInfo.ObjectCapacity); 247 * (long)m_scene.RegionInfo.ObjectCapacity
248 / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) );
249 // m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax);
217 return simMax; 250 return simMax;
218 } 251 }
219 } 252 }
@@ -224,6 +257,9 @@ namespace OpenSim.Region.CoreModules.World.Land
224 257
225 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) 258 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
226 { 259 {
260 if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
261 return;
262
227 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 263 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
228 // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); 264 // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
229 uint regionFlags = (uint)(RegionFlags.PublicAllowed 265 uint regionFlags = (uint)(RegionFlags.PublicAllowed
@@ -248,14 +284,15 @@ namespace OpenSim.Region.CoreModules.World.Land
248 remote_client.SendLandProperties(seq_id, 284 remote_client.SendLandProperties(seq_id,
249 snap_selection, request_result, this, 285 snap_selection, request_result, this,
250 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, 286 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
251 GetParcelMaxPrimCount(), 287 GetParcelBasePrimCount(),
252 GetSimulatorMaxPrimCount(), regionFlags); 288 GetSimulatorMaxPrimCount(), regionFlags);
253 } 289 }
254 290
255 public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) 291 public bool UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client, out bool snap_selection, out bool needOverlay)
256 { 292 {
257 //Needs later group support 293 //Needs later group support
258 bool snap_selection = false; 294 snap_selection = false;
295 needOverlay = false;
259 LandData newData = LandData.Copy(); 296 LandData newData = LandData.Copy();
260 297
261 uint allowedDelta = 0; 298 uint allowedDelta = 0;
@@ -264,7 +301,7 @@ namespace OpenSim.Region.CoreModules.World.Land
264 // ParcelFlags.ForSaleObjects 301 // ParcelFlags.ForSaleObjects
265 // ParcelFlags.LindenHome 302 // ParcelFlags.LindenHome
266 303
267 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) 304 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, false))
268 { 305 {
269 allowedDelta |= (uint)(ParcelFlags.AllowLandmark | 306 allowedDelta |= (uint)(ParcelFlags.AllowLandmark |
270 ParcelFlags.AllowTerraform | 307 ParcelFlags.AllowTerraform |
@@ -277,9 +314,12 @@ namespace OpenSim.Region.CoreModules.World.Land
277 ParcelFlags.AllowAPrimitiveEntry | 314 ParcelFlags.AllowAPrimitiveEntry |
278 ParcelFlags.AllowGroupObjectEntry | 315 ParcelFlags.AllowGroupObjectEntry |
279 ParcelFlags.AllowFly); 316 ParcelFlags.AllowFly);
317 newData.SeeAVs = args.SeeAVs;
318 newData.AnyAVSounds = args.AnyAVSounds;
319 newData.GroupAVSounds = args.GroupAVSounds;
280 } 320 }
281 321
282 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale)) 322 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale, true))
283 { 323 {
284 if (args.AuthBuyerID != newData.AuthBuyerID || 324 if (args.AuthBuyerID != newData.AuthBuyerID ||
285 args.SalePrice != newData.SalePrice) 325 args.SalePrice != newData.SalePrice)
@@ -302,30 +342,30 @@ namespace OpenSim.Region.CoreModules.World.Land
302 allowedDelta |= (uint)ParcelFlags.ForSale; 342 allowedDelta |= (uint)ParcelFlags.ForSale;
303 } 343 }
304 344
305 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces)) 345 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces, false))
306 { 346 {
307 newData.Category = args.Category; 347 newData.Category = args.Category;
308 348
309 allowedDelta |= (uint)(ParcelFlags.ShowDirectory | 349 allowedDelta |= (uint)(ParcelFlags.ShowDirectory |
310 ParcelFlags.AllowPublish | 350 ParcelFlags.AllowPublish |
311 ParcelFlags.MaturePublish); 351 ParcelFlags.MaturePublish) | (uint)(1 << 23);
312 } 352 }
313 353
314 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) 354 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity, false))
315 { 355 {
316 newData.Description = args.Desc; 356 newData.Description = args.Desc;
317 newData.Name = args.Name; 357 newData.Name = args.Name;
318 newData.SnapshotID = args.SnapshotID; 358 newData.SnapshotID = args.SnapshotID;
319 } 359 }
320 360
321 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint)) 361 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint, false))
322 { 362 {
323 newData.LandingType = args.LandingType; 363 newData.LandingType = args.LandingType;
324 newData.UserLocation = args.UserLocation; 364 newData.UserLocation = args.UserLocation;
325 newData.UserLookAt = args.UserLookAt; 365 newData.UserLookAt = args.UserLookAt;
326 } 366 }
327 367
328 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia)) 368 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia, false))
329 { 369 {
330 newData.MediaAutoScale = args.MediaAutoScale; 370 newData.MediaAutoScale = args.MediaAutoScale;
331 newData.MediaID = args.MediaID; 371 newData.MediaID = args.MediaID;
@@ -346,7 +386,7 @@ namespace OpenSim.Region.CoreModules.World.Land
346 ParcelFlags.UseEstateVoiceChan); 386 ParcelFlags.UseEstateVoiceChan);
347 } 387 }
348 388
349 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses)) 389 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false))
350 { 390 {
351 newData.PassHours = args.PassHours; 391 newData.PassHours = args.PassHours;
352 newData.PassPrice = args.PassPrice; 392 newData.PassPrice = args.PassPrice;
@@ -354,13 +394,13 @@ namespace OpenSim.Region.CoreModules.World.Land
354 allowedDelta |= (uint)ParcelFlags.UsePassList; 394 allowedDelta |= (uint)ParcelFlags.UsePassList;
355 } 395 }
356 396
357 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed)) 397 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed, false))
358 { 398 {
359 allowedDelta |= (uint)(ParcelFlags.UseAccessGroup | 399 allowedDelta |= (uint)(ParcelFlags.UseAccessGroup |
360 ParcelFlags.UseAccessList); 400 ParcelFlags.UseAccessList);
361 } 401 }
362 402
363 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned)) 403 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned, false))
364 { 404 {
365 allowedDelta |= (uint)(ParcelFlags.UseBanList | 405 allowedDelta |= (uint)(ParcelFlags.UseBanList |
366 ParcelFlags.DenyAnonymous | 406 ParcelFlags.DenyAnonymous |
@@ -372,9 +412,16 @@ namespace OpenSim.Region.CoreModules.World.Land
372 uint preserve = LandData.Flags & ~allowedDelta; 412 uint preserve = LandData.Flags & ~allowedDelta;
373 newData.Flags = preserve | (args.ParcelFlags & allowedDelta); 413 newData.Flags = preserve | (args.ParcelFlags & allowedDelta);
374 414
415 uint curdelta = LandData.Flags ^ newData.Flags;
416 curdelta &= (uint)(ParcelFlags.SoundLocal);
417
418 if(curdelta != 0 || newData.SeeAVs != LandData.SeeAVs)
419 needOverlay = true;
420
375 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 421 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
376 SendLandUpdateToAvatarsOverMe(snap_selection); 422 return true;
377 } 423 }
424 return false;
378 } 425 }
379 426
380 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) 427 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
@@ -395,7 +442,7 @@ namespace OpenSim.Region.CoreModules.World.Land
395 UUID previousOwner = LandData.OwnerID; 442 UUID previousOwner = LandData.OwnerID;
396 443
397 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 444 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
398 m_scene.EventManager.TriggerParcelPrimCountUpdate(); 445// m_scene.EventManager.TriggerParcelPrimCountUpdate();
399 SendLandUpdateToAvatarsOverMe(true); 446 SendLandUpdateToAvatarsOverMe(true);
400 447
401 if (sellObjects) SellLandObjects(previousOwner); 448 if (sellObjects) SellLandObjects(previousOwner);
@@ -568,6 +615,7 @@ namespace OpenSim.Region.CoreModules.World.Land
568 615
569 public void SendLandUpdateToAvatarsOverMe(bool snap_selection) 616 public void SendLandUpdateToAvatarsOverMe(bool snap_selection)
570 { 617 {
618 m_scene.EventManager.TriggerParcelPrimCountUpdate();
571 m_scene.ForEachRootScenePresence(delegate(ScenePresence avatar) 619 m_scene.ForEachRootScenePresence(delegate(ScenePresence avatar)
572 { 620 {
573 ILandObject over = null; 621 ILandObject over = null;
@@ -594,6 +642,7 @@ namespace OpenSim.Region.CoreModules.World.Land
594 avatar.Invulnerable = true; 642 avatar.Invulnerable = true;
595 643
596 SendLandUpdateToClient(snap_selection, avatar.ControllingClient); 644 SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
645 avatar.currentParcelUUID = LandData.GlobalID;
597 } 646 }
598 } 647 }
599 }); 648 });
@@ -722,10 +771,11 @@ namespace OpenSim.Region.CoreModules.World.Land
722 /// </summary> 771 /// </summary>
723 private void UpdateAABBAndAreaValues() 772 private void UpdateAABBAndAreaValues()
724 { 773 {
725 int min_x = 10000; 774
726 int min_y = 10000; 775 int min_x = Int32.MaxValue;
727 int max_x = 0; 776 int min_y = Int32.MaxValue;
728 int max_y = 0; 777 int max_x = Int32.MinValue;
778 int max_y = Int32.MinValue;
729 int tempArea = 0; 779 int tempArea = 0;
730 int x, y; 780 int x, y;
731 for (x = 0; x < LandBitmap.GetLength(0); x++) 781 for (x = 0; x < LandBitmap.GetLength(0); x++)
@@ -734,10 +784,14 @@ namespace OpenSim.Region.CoreModules.World.Land
734 { 784 {
735 if (LandBitmap[x, y] == true) 785 if (LandBitmap[x, y] == true)
736 { 786 {
737 if (min_x > x) min_x = x; 787 if (min_x > x)
738 if (min_y > y) min_y = y; 788 min_x = x;
739 if (max_x < x) max_x = x; 789 if (min_y > y)
740 if (max_y < y) max_y = y; 790 min_y = y;
791 if (max_x < x)
792 max_x = x;
793 if (max_y < y)
794 max_y = y;
741 tempArea += landUnit * landUnit; //16sqm peice of land 795 tempArea += landUnit * landUnit; //16sqm peice of land
742 } 796 }
743 } 797 }
@@ -745,24 +799,42 @@ namespace OpenSim.Region.CoreModules.World.Land
745 int tx = min_x * landUnit; 799 int tx = min_x * landUnit;
746 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) 800 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
747 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); 801 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
802 int htx;
803 if (tx >= ((int)m_scene.RegionInfo.RegionSizeX))
804 htx = (int)m_scene.RegionInfo.RegionSizeX - 1;
805 else
806 htx = tx;
807
748 int ty = min_y * landUnit; 808 int ty = min_y * landUnit;
749 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1)) 809 int hty;
750 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1); 810
811 if (ty >= ((int)m_scene.RegionInfo.RegionSizeY))
812 hty = (int)m_scene.RegionInfo.RegionSizeY - 1;
813 else
814 hty = ty;
751 815
752 LandData.AABBMin = 816 LandData.AABBMin =
753 new Vector3( 817 new Vector3(
754 (float)(min_x * landUnit), (float)(min_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 818 (float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0);
755 819
820 max_x++;
756 tx = max_x * landUnit; 821 tx = max_x * landUnit;
757 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) 822 if (tx >= ((int)m_scene.RegionInfo.RegionSizeX))
758 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); 823 htx = (int)m_scene.RegionInfo.RegionSizeX - 1;
759 ty = max_y * landUnit; 824 else
760 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1)) 825 htx = tx;
761 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1); 826
827 max_y++;
828 ty = max_y * 4;
829
830 if (ty >= ((int)m_scene.RegionInfo.RegionSizeY))
831 hty = (int)m_scene.RegionInfo.RegionSizeY - 1;
832 else
833 hty = ty;
762 834
763 LandData.AABBMax 835 LandData.AABBMax
764 = new Vector3( 836 = new Vector3(
765 (float)(max_x * landUnit), (float)(max_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 837 (float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0);
766 838
767 LandData.Area = tempArea; 839 LandData.Area = tempArea;
768 } 840 }
@@ -778,7 +850,6 @@ namespace OpenSim.Region.CoreModules.World.Land
778 public void SetLandBitmap(bool[,] bitmap) 850 public void SetLandBitmap(bool[,] bitmap)
779 { 851 {
780 LandBitmap = bitmap; 852 LandBitmap = bitmap;
781 // m_log.DebugFormat("{0} SetLandBitmap. BitmapSize=<{1},{2}>", LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
782 ForceUpdateLandInfo(); 853 ForceUpdateLandInfo();
783 } 854 }
784 855
@@ -879,13 +950,32 @@ namespace OpenSim.Region.CoreModules.World.Land
879 private byte[] ConvertLandBitmapToBytes() 950 private byte[] ConvertLandBitmapToBytes()
880 { 951 {
881 byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8]; 952 byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
882 byte tempByte = 0; 953
883 int byteNum = 0; 954 int tempByte = 0;
884 int i = 0; 955 int i, byteNum = 0;
956 int mask = 1;
957 i = 0;
885 for (int y = 0; y < LandBitmap.GetLength(1); y++) 958 for (int y = 0; y < LandBitmap.GetLength(1); y++)
886 { 959 {
887 for (int x = 0; x < LandBitmap.GetLength(0); x++) 960 for (int x = 0; x < LandBitmap.GetLength(0); x++)
888 { 961 {
962 if (LandBitmap[x, y])
963 tempByte |= mask;
964 mask = mask << 1;
965 if (mask == 0x100)
966 {
967 mask = 1;
968 tempConvertArr[byteNum++] = (byte)tempByte;
969 tempByte = 0;
970 }
971 }
972 }
973
974 if(tempByte != 0 && byteNum < 512)
975 tempConvertArr[byteNum] = (byte)tempByte;
976
977
978/*
889 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); 979 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
890 if (i % 8 == 0) 980 if (i % 8 == 0)
891 { 981 {
@@ -894,10 +984,13 @@ namespace OpenSim.Region.CoreModules.World.Land
894 i = 0; 984 i = 0;
895 byteNum++; 985 byteNum++;
896 } 986 }
987<<<<<<< HEAD
897 } 988 }
898 } 989 }
899 // m_log.DebugFormat("{0} ConvertLandBitmapToBytes. BitmapSize=<{1},{2}>", 990 // m_log.DebugFormat("{0} ConvertLandBitmapToBytes. BitmapSize=<{1},{2}>",
900 // LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); 991 // LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
992=======
993 */
901 return tempConvertArr; 994 return tempConvertArr;
902 } 995 }
903 996
@@ -951,7 +1044,7 @@ namespace OpenSim.Region.CoreModules.World.Land
951 1044
952 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client) 1045 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client)
953 { 1046 {
954 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) 1047 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
955 { 1048 {
956 List<uint> resultLocalIDs = new List<uint>(); 1049 List<uint> resultLocalIDs = new List<uint>();
957 try 1050 try
@@ -1001,7 +1094,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1001 /// </param> 1094 /// </param>
1002 public void SendLandObjectOwners(IClientAPI remote_client) 1095 public void SendLandObjectOwners(IClientAPI remote_client)
1003 { 1096 {
1004 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) 1097 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
1005 { 1098 {
1006 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>(); 1099 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>();
1007 List<UUID> groups = new List<UUID>(); 1100 List<UUID> groups = new List<UUID>();
@@ -1233,6 +1326,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1233 public void SetMediaUrl(string url) 1326 public void SetMediaUrl(string url)
1234 { 1327 {
1235 LandData.MediaURL = url; 1328 LandData.MediaURL = url;
1329 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData);
1236 SendLandUpdateToAvatarsOverMe(); 1330 SendLandUpdateToAvatarsOverMe();
1237 } 1331 }
1238 1332
@@ -1243,6 +1337,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1243 public void SetMusicUrl(string url) 1337 public void SetMusicUrl(string url)
1244 { 1338 {
1245 LandData.MusicURL = url; 1339 LandData.MusicURL = url;
1340 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData);
1246 SendLandUpdateToAvatarsOverMe(); 1341 SendLandUpdateToAvatarsOverMe();
1247 } 1342 }
1248 1343
@@ -1257,6 +1352,17 @@ namespace OpenSim.Region.CoreModules.World.Land
1257 1352
1258 #endregion 1353 #endregion
1259 1354
1355 private void OnFrame()
1356 {
1357 m_expiryCounter++;
1358
1359 if (m_expiryCounter >= 50)
1360 {
1361 ExpireAccessList();
1362 m_expiryCounter = 0;
1363 }
1364 }
1365
1260 private void ExpireAccessList() 1366 private void ExpireAccessList()
1261 { 1367 {
1262 List<LandAccessEntry> delete = new List<LandAccessEntry>(); 1368 List<LandAccessEntry> delete = new List<LandAccessEntry>();
@@ -1267,7 +1373,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1267 delete.Add(entry); 1373 delete.Add(entry);
1268 } 1374 }
1269 foreach (LandAccessEntry entry in delete) 1375 foreach (LandAccessEntry entry in delete)
1376 {
1270 LandData.ParcelAccessList.Remove(entry); 1377 LandData.ParcelAccessList.Remove(entry);
1378 ScenePresence presence;
1379
1380 if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
1381 {
1382 ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
1383 if (land.LandData.LocalID == LandData.LocalID)
1384 {
1385 Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
1386 presence.TeleportWithMomentum(pos, null);
1387 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
1388 }
1389 }
1390 m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
1391 }
1271 1392
1272 if (delete.Count > 0) 1393 if (delete.Count > 0)
1273 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); 1394 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/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
index 796a15f..5155804 100644
--- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
@@ -112,7 +112,6 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
112 //} 112 //}
113 //t = System.Environment.TickCount - t; 113 //t = System.Environment.TickCount - t;
114 //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t); 114 //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t);
115
116 if (drawPrimVolume) 115 if (drawPrimVolume)
117 { 116 {
118 DrawObjectVolume(m_scene, mapbmp); 117 DrawObjectVolume(m_scene, mapbmp);
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
index 9f23141..0ec2053 100644
--- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
+++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
@@ -288,7 +288,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
288 if (mapbmp.Width != hm.Width || mapbmp.Height != hm.Height) 288 if (mapbmp.Width != hm.Width || mapbmp.Height != hm.Height)
289 { 289 {
290 m_log.ErrorFormat("{0} TerrainToBitmap. Passed bitmap wrong dimensions. passed=<{1},{2}>, size=<{3},{4}>", 290 m_log.ErrorFormat("{0} TerrainToBitmap. Passed bitmap wrong dimensions. passed=<{1},{2}>, size=<{3},{4}>",
291 LogHeader, mapbmp.Width, mapbmp.Height, hm.Width, hm.Height); 291 "[TEXTURED MAP TILE RENDERER]", mapbmp.Width, mapbmp.Height, hm.Width, hm.Height);
292 } 292 }
293 293
294 // These textures should be in the AssetCache anyway, as every client conneting to this 294 // These textures should be in the AssetCache anyway, as every client conneting to this
@@ -371,8 +371,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
371 // first, rescale h to 0.0 - 1.0 371 // first, rescale h to 0.0 - 1.0
372 hmod = (hmod - low) / (high - low); 372 hmod = (hmod - low) / (high - low);
373 // now we have to split: 0.00 => color1, 0.33 => color2, 0.67 => color3, 1.00 => color4 373 // now we have to split: 0.00 => color1, 0.33 => color2, 0.67 => color3, 1.00 => color4
374 if (hmod < 1f/3f) hsv = interpolateHSV(ref hsv1, ref hsv2, hmod * 3f); 374 if (hmod < 1f / 3f) hsv = interpolateHSV(ref hsv1, ref hsv2, hmod * 3f);
375 else if (hmod < 2f/3f) hsv = interpolateHSV(ref hsv2, ref hsv3, (hmod * 3f) - 1f); 375 else if (hmod < 2f / 3f) hsv = interpolateHSV(ref hsv2, ref hsv3, (hmod * 3f) - 1f);
376 else hsv = interpolateHSV(ref hsv3, ref hsv4, (hmod * 3f) - 2f); 376 else hsv = interpolateHSV(ref hsv3, ref hsv4, (hmod * 3f) - 2f);
377 } 377 }
378 378
diff --git a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
index 0a4e83e..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,8 +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 {0}", presence.Name); 213 if (m_enableWindlight && m_scene.RegionInfo.WindlightSettings.valid)
211 214 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
212 SendProfileToClient(presence.ControllingClient); 215 SendProfileToClient(presence.ControllingClient);
213 } 216 }
214 217
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index 2abc910..0e0f05f 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -173,6 +173,13 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
173 return false; 173 return false;
174 } 174 }
175 175
176 if ((perms & (uint)PermissionMask.Copy) == 0)
177 {
178 if (m_dialogModule != null)
179 m_dialogModule.SendAlertToUser(remoteClient, "This sale has been blocked by the permissions system");
180 return false;
181 }
182
176 AssetBase asset = m_scene.CreateAsset( 183 AssetBase asset = m_scene.CreateAsset(
177 group.GetPartName(localID), 184 group.GetPartName(localID),
178 group.GetPartDescription(localID), 185 group.GetPartDescription(localID),
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 780ec69..12e8fb1 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -43,8 +43,8 @@ using PermissionMask = OpenSim.Framework.PermissionMask;
43 43
44namespace OpenSim.Region.CoreModules.World.Permissions 44namespace OpenSim.Region.CoreModules.World.Permissions
45{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PermissionsModule")] 46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DefaultPermissionsModule")]
47 public class PermissionsModule : INonSharedRegionModule, IPermissionsModule 47 public class DefaultPermissionsModule : INonSharedRegionModule, IPermissionsModule
48 { 48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
@@ -349,7 +349,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
349 349
350 public string Name 350 public string Name
351 { 351 {
352 get { return "PermissionsModule"; } 352 get { return "DefaultPermissionsModule"; }
353 } 353 }
354 354
355 public Type ReplaceableInterface 355 public Type ReplaceableInterface
@@ -1052,7 +1052,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
1052 return GenericObjectPermission(editorID, objectID, false); 1052 return GenericObjectPermission(editorID, objectID, false);
1053 } 1053 }
1054 1054
1055 private bool CanEditParcelProperties(UUID user, ILandObject parcel, GroupPowers p, Scene scene) 1055 private bool CanEditParcelProperties(UUID user, ILandObject parcel, GroupPowers p, Scene scene, bool allowManager)
1056 { 1056 {
1057 DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); 1057 DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name);
1058 if (m_bypassPermissions) return m_bypassPermissionsValue; 1058 if (m_bypassPermissions) return m_bypassPermissionsValue;
diff --git a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs
index 710c8da..8d192ba 100644
--- a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs
@@ -271,8 +271,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
271 float totalFrameTime = stats[8]; 271 float totalFrameTime = stats[8];
272// float netFrameTime = stats.StatsBlock[9].StatValue; // Ignored - not used by OpenSimulator 272// float netFrameTime = stats.StatsBlock[9].StatValue; // Ignored - not used by OpenSimulator
273 float physicsFrameTime = stats[10]; 273 float physicsFrameTime = stats[10];
274 float otherFrameTime = stats[11]; 274 float otherFrameTime = stats[12];
275// float imageFrameTime = stats.StatsBlock[12].StatValue; // Ignored 275// float imageFrameTime = stats.StatsBlock[11].StatValue; // Ignored
276 float inPacketsPerSecond = stats[13]; 276 float inPacketsPerSecond = stats[13];
277 float outPacketsPerSecond = stats[14]; 277 float outPacketsPerSecond = stats[14];
278 float unackedBytes = stats[15]; 278 float unackedBytes = stats[15];
@@ -280,7 +280,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
280 float pendingDownloads = stats[17]; 280 float pendingDownloads = stats[17];
281 float pendingUploads = stats[18]; 281 float pendingUploads = stats[18];
282 float activeScripts = stats[19]; 282 float activeScripts = stats[19];
283 float scriptLinesPerSecond = stats[20]; 283 float scriptLinesPerSecond = stats[23];
284 284
285 StringBuilder sb = new StringBuilder(); 285 StringBuilder sb = new StringBuilder();
286 sb.AppendFormat("Scene statistics for {0}\n", m_scene.RegionInfo.RegionName); 286 sb.AppendFormat("Scene statistics for {0}\n", m_scene.RegionInfo.RegionName);
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
index 75a8295..e6a0205 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);
@@ -118,10 +131,14 @@ namespace OpenSim.Region.CoreModules.World.Region
118 public void ScheduleRestart(UUID initiator, string message, int[] alerts, bool notice) 131 public void ScheduleRestart(UUID initiator, string message, int[] alerts, bool notice)
119 { 132 {
120 if (m_CountdownTimer != null) 133 if (m_CountdownTimer != null)
121 return; 134 {
135 m_CountdownTimer.Stop();
136 m_CountdownTimer = null;
137 }
122 138
123 if (alerts == null) 139 if (alerts == null)
124 { 140 {
141 CreateMarkerFile();
125 m_Scene.RestartNow(); 142 m_Scene.RestartNow();
126 return; 143 return;
127 } 144 }
@@ -129,25 +146,28 @@ namespace OpenSim.Region.CoreModules.World.Region
129 m_Message = message; 146 m_Message = message;
130 m_Initiator = initiator; 147 m_Initiator = initiator;
131 m_Notice = notice; 148 m_Notice = notice;
149 m_CurrentAlerts = alerts;
132 m_Alerts = new List<int>(alerts); 150 m_Alerts = new List<int>(alerts);
133 m_Alerts.Sort(); 151 m_Alerts.Sort();
134 m_Alerts.Reverse(); 152 m_Alerts.Reverse();
135 153
136 if (m_Alerts[0] == 0) 154 if (m_Alerts[0] == 0)
137 { 155 {
156 CreateMarkerFile();
138 m_Scene.RestartNow(); 157 m_Scene.RestartNow();
139 return; 158 return;
140 } 159 }
141 160
142 int nextInterval = DoOneNotice(); 161 int nextInterval = DoOneNotice(true);
143 162
144 SetTimer(nextInterval); 163 SetTimer(nextInterval);
145 } 164 }
146 165
147 public int DoOneNotice() 166 public int DoOneNotice(bool sendOut)
148 { 167 {
149 if (m_Alerts.Count == 0 || m_Alerts[0] == 0) 168 if (m_Alerts.Count == 0 || m_Alerts[0] == 0)
150 { 169 {
170 CreateMarkerFile();
151 m_Scene.RestartNow(); 171 m_Scene.RestartNow();
152 return 0; 172 return 0;
153 } 173 }
@@ -168,34 +188,37 @@ namespace OpenSim.Region.CoreModules.World.Region
168 188
169 m_Alerts.RemoveAt(0); 189 m_Alerts.RemoveAt(0);
170 190
171 int minutes = currentAlert / 60; 191 if (sendOut)
172 string currentAlertString = String.Empty;
173 if (minutes > 0)
174 { 192 {
175 if (minutes == 1) 193 int minutes = currentAlert / 60;
176 currentAlertString += "1 minute"; 194 string currentAlertString = String.Empty;
177 else 195 if (minutes > 0)
178 currentAlertString += String.Format("{0} minutes", minutes); 196 {
197 if (minutes == 1)
198 currentAlertString += "1 minute";
199 else
200 currentAlertString += String.Format("{0} minutes", minutes);
201 if ((currentAlert % 60) != 0)
202 currentAlertString += " and ";
203 }
179 if ((currentAlert % 60) != 0) 204 if ((currentAlert % 60) != 0)
180 currentAlertString += " and "; 205 {
181 } 206 int seconds = currentAlert % 60;
182 if ((currentAlert % 60) != 0) 207 if (seconds == 1)
183 { 208 currentAlertString += "1 second";
184 int seconds = currentAlert % 60; 209 else
185 if (seconds == 1) 210 currentAlertString += String.Format("{0} seconds", seconds);
186 currentAlertString += "1 second"; 211 }
187 else
188 currentAlertString += String.Format("{0} seconds", seconds);
189 }
190 212
191 string msg = String.Format(m_Message, currentAlertString); 213 string msg = String.Format(m_Message, currentAlertString);
192 214
193 if (m_DialogModule != null && msg != String.Empty) 215 if (m_DialogModule != null && msg != String.Empty)
194 { 216 {
195 if (m_Notice) 217 if (m_Notice)
196 m_DialogModule.SendGeneralAlert(msg); 218 m_DialogModule.SendGeneralAlert(msg);
197 else 219 else
198 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg); 220 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg);
221 }
199 } 222 }
200 223
201 return currentAlert - nextAlert; 224 return currentAlert - nextAlert;
@@ -226,7 +249,27 @@ namespace OpenSim.Region.CoreModules.World.Region
226 249
227 private void OnTimer(object source, ElapsedEventArgs e) 250 private void OnTimer(object source, ElapsedEventArgs e)
228 { 251 {
229 SetTimer(DoOneNotice()); 252 int nextInterval = DoOneNotice(true);
253
254 SetTimer(nextInterval);
255 }
256
257 public void DelayRestart(int seconds, string message)
258 {
259 if (m_CountdownTimer == null)
260 return;
261
262 m_CountdownTimer.Stop();
263 m_CountdownTimer = null;
264
265 m_Alerts = new List<int>(m_CurrentAlerts);
266 m_Alerts.Add(seconds);
267 m_Alerts.Sort();
268 m_Alerts.Reverse();
269
270 int nextInterval = DoOneNotice(false);
271
272 SetTimer(nextInterval);
230 } 273 }
231 274
232 public void AbortRestart(string message) 275 public void AbortRestart(string message)
@@ -236,8 +279,12 @@ namespace OpenSim.Region.CoreModules.World.Region
236 m_CountdownTimer.Stop(); 279 m_CountdownTimer.Stop();
237 m_CountdownTimer = null; 280 m_CountdownTimer = null;
238 if (m_DialogModule != null && message != String.Empty) 281 if (m_DialogModule != null && message != String.Empty)
239 m_DialogModule.SendGeneralAlert(message); 282 m_DialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
283 //m_DialogModule.SendGeneralAlert(message);
240 } 284 }
285 if (m_MarkerPath != String.Empty)
286 File.Delete(Path.Combine(m_MarkerPath,
287 m_Scene.RegionInfo.RegionID.ToString()));
241 } 288 }
242 289
243 private void HandleRegionRestart(string module, string[] args) 290 private void HandleRegionRestart(string module, string[] args)
@@ -282,5 +329,25 @@ namespace OpenSim.Region.CoreModules.World.Region
282 329
283 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice); 330 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
284 } 331 }
332
333 protected void CreateMarkerFile()
334 {
335 if (m_MarkerPath == String.Empty)
336 return;
337
338 string path = Path.Combine(m_MarkerPath, m_Scene.RegionInfo.RegionID.ToString());
339 try
340 {
341 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
342 FileStream fs = File.Create(path);
343 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
344 Byte[] buf = enc.GetBytes(pidstring);
345 fs.Write(buf, 0, buf.Length);
346 fs.Close();
347 }
348 catch (Exception)
349 {
350 }
351 }
285 } 352 }
286} \ No newline at end of file 353}
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index d093224..9c99c19 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -48,6 +48,18 @@ namespace OpenSim.Region.CoreModules.World.Sound
48 48
49 private Scene m_scene; 49 private Scene m_scene;
50 50
51 public enum SoundFlags: byte
52 {
53 NONE = 0,
54 LOOP = 1 << 0,
55 SYNC_MASTER = 1<<1,
56 SYNC_SLAVE = 1<<2,
57 SYNC_PENDING = 1<<3,
58 QUEUE = 1<<4,
59 STOP = 1<<5,
60 SYNC_MASK = SYNC_MASTER | SYNC_SLAVE | SYNC_PENDING
61 }
62
51 public bool Enabled { get; private set; } 63 public bool Enabled { get; private set; }
52 64
53 public float MaxDistance { get; private set; } 65 public float MaxDistance { get; private set; }
@@ -124,26 +136,30 @@ namespace OpenSim.Region.CoreModules.World.Sound
124 if (radius == 0) 136 if (radius == 0)
125 radius = MaxDistance; 137 radius = MaxDistance;
126 138
127 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 139 if (part.SoundQueueing)
140 flags |= (byte)SoundFlags.QUEUE;
141
142 if (grp.IsAttachment)
128 { 143 {
129 double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); 144 ScenePresence ssp = null;
130 if (dis > MaxDistance) // Max audio distance 145 if (!m_scene.TryGetScenePresence(grp.AttachedAvatar, out ssp))
131 return; 146 return;
132 147
133 if (grp.IsAttachment) 148 if (!ssp.ParcelAllowThisAvatarSounds)
134 { 149 return;
135 if (grp.HasPrivateAttachmentPoint && sp.ControllingClient.AgentId != grp.OwnerID)
136 return;
137 150
138 if (sp.ControllingClient.AgentId == grp.OwnerID) 151 if (grp.HasPrivateAttachmentPoint)
139 dis = 0; 152 {
153 ssp.ControllingClient.SendPlayAttachedSound(soundID, objectID,
154 ownerID, (float)gain, flags);
155 return;
140 } 156 }
157 }
141 158
142 // Scale by distance 159 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
143 double thisSpGain = gain * ((radius - dis) / radius); 160 {
144
145 sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, 161 sp.ControllingClient.SendPlayAttachedSound(soundID, objectID,
146 ownerID, (float)thisSpGain, flags); 162 ownerID, (float)gain, flags);
147 }); 163 });
148 } 164 }
149 165
@@ -151,20 +167,33 @@ namespace OpenSim.Region.CoreModules.World.Sound
151 UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) 167 UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius)
152 { 168 {
153 SceneObjectPart part; 169 SceneObjectPart part;
170 ScenePresence ssp = null;
154 if (!m_scene.TryGetSceneObjectPart(objectID, out part)) 171 if (!m_scene.TryGetSceneObjectPart(objectID, out part))
155 { 172 {
156 ScenePresence sp; 173 if (!m_scene.TryGetScenePresence(ownerID, out ssp))
157 if (!m_scene.TryGetScenePresence(ownerID, out sp)) 174 return;
175 if (!ssp.ParcelAllowThisAvatarSounds)
158 return; 176 return;
159 } 177 }
160 else 178 else
161 { 179 {
162 SceneObjectGroup grp = part.ParentGroup; 180 SceneObjectGroup grp = part.ParentGroup;
163 181
164 if (grp.IsAttachment && grp.AttachmentPoint > 30) 182 if (grp.IsAttachment)
165 { 183 {
166 objectID = ownerID; 184 if (!m_scene.TryGetScenePresence(grp.AttachedAvatar, out ssp))
167 parentID = ownerID; 185 return;
186
187 if (!ssp.ParcelAllowThisAvatarSounds)
188 return;
189
190 if (grp.HasPrivateAttachmentPoint)
191 {
192 ssp.ControllingClient.SendTriggeredSound(soundId, ownerID,
193 objectID, parentID, handle, position,
194 (float)gain);
195 return;
196 }
168 } 197 }
169 } 198 }
170 199
@@ -174,16 +203,12 @@ namespace OpenSim.Region.CoreModules.World.Sound
174 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 203 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
175 { 204 {
176 double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); 205 double dis = Util.GetDistanceTo(sp.AbsolutePosition, position);
177 206 if (dis > radius) // Max audio distance
178 if (dis > MaxDistance) // Max audio distance
179 return; 207 return;
180 208
181 // Scale by distance
182 double thisSpGain = gain * ((radius - dis) / radius);
183
184 sp.ControllingClient.SendTriggeredSound(soundId, ownerID, 209 sp.ControllingClient.SendTriggeredSound(soundId, ownerID,
185 objectID, parentID, handle, position, 210 objectID, parentID, handle, position,
186 (float)thisSpGain); 211 (float)gain);
187 }); 212 });
188 } 213 }
189 214
@@ -198,40 +223,13 @@ namespace OpenSim.Region.CoreModules.World.Sound
198 223
199 private static void StopSound(SceneObjectPart m_host) 224 private static void StopSound(SceneObjectPart m_host)
200 { 225 {
201 m_host.AdjustSoundGain(0); 226// m_host.AdjustSoundGain(0);
202 // Xantor 20080528: Clear prim data of sound instead 227 m_host.Sound = UUID.Zero;
203 if (m_host.ParentGroup.LoopSoundSlavePrims.Contains(m_host)) 228 m_host.SoundFlags = (byte)SoundFlags.STOP;
204 { 229 m_host.SoundRadius = 0;
205 if (m_host.ParentGroup.LoopSoundMasterPrim == m_host) 230 m_host.SoundGain = 0;
206 { 231 m_host.ScheduleFullUpdate();
207 foreach (SceneObjectPart part in m_host.ParentGroup.LoopSoundSlavePrims) 232 m_host.SendFullUpdateToAllClients();
208 {
209 part.Sound = UUID.Zero;
210 part.SoundFlags = 1 << 5;
211 part.SoundRadius = 0;
212 part.ScheduleFullUpdate();
213 part.SendFullUpdateToAllClients();
214 }
215 m_host.ParentGroup.LoopSoundMasterPrim = null;
216 m_host.ParentGroup.LoopSoundSlavePrims.Clear();
217 }
218 else
219 {
220 m_host.Sound = UUID.Zero;
221 m_host.SoundFlags = 1 << 5;
222 m_host.SoundRadius = 0;
223 m_host.ScheduleFullUpdate();
224 m_host.SendFullUpdateToAllClients();
225 }
226 }
227 else
228 {
229 m_host.Sound = UUID.Zero;
230 m_host.SoundFlags = 1 << 5;
231 m_host.SoundRadius = 0;
232 m_host.ScheduleFullUpdate();
233 m_host.SendFullUpdateToAllClients();
234 }
235 } 233 }
236 234
237 public virtual void PreloadSound(UUID objectID, UUID soundID, float radius) 235 public virtual void PreloadSound(UUID objectID, UUID soundID, float radius)
@@ -248,7 +246,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
248 246
249 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 247 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
250 { 248 {
251 if (!(Util.GetDistanceTo(sp.AbsolutePosition, part.AbsolutePosition) >= MaxDistance)) 249 if (Util.GetDistanceTo(sp.AbsolutePosition, part.AbsolutePosition) < radius)
252 sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); 250 sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID);
253 }); 251 });
254 } 252 }
@@ -262,21 +260,24 @@ namespace OpenSim.Region.CoreModules.World.Sound
262 // 20080530 Updated to remove code duplication 260 // 20080530 Updated to remove code duplication
263 // 20080530 Stop sound if there is one, otherwise volume only changes don't work 261 // 20080530 Stop sound if there is one, otherwise volume only changes don't work
264 public void LoopSound(UUID objectID, UUID soundID, 262 public void LoopSound(UUID objectID, UUID soundID,
265 double volume, double radius, bool isMaster) 263 double volume, double radius, bool isMaster, bool isSlave)
266 { 264 {
267 SceneObjectPart m_host; 265 SceneObjectPart m_host;
268 if (!m_scene.TryGetSceneObjectPart(objectID, out m_host)) 266 if (!m_scene.TryGetSceneObjectPart(objectID, out m_host))
269 return; 267 return;
270 268
269 byte iflags = 1; // looping
271 if (isMaster) 270 if (isMaster)
272 m_host.ParentGroup.LoopSoundMasterPrim = m_host; 271 iflags |= (byte)SoundFlags.SYNC_MASTER;
273 272 // TODO check viewer seems to accept both
274 if (m_host.Sound != UUID.Zero) 273 if (isSlave)
275 StopSound(m_host); 274 iflags |= (byte)SoundFlags.SYNC_SLAVE;
275 if (m_host.SoundQueueing)
276 iflags |= (byte)SoundFlags.QUEUE;
276 277
277 m_host.Sound = soundID; 278 m_host.Sound = soundID;
278 m_host.SoundGain = volume; 279 m_host.SoundGain = volume;
279 m_host.SoundFlags = 1; // looping 280 m_host.SoundFlags = iflags;
280 m_host.SoundRadius = radius; 281 m_host.SoundRadius = radius;
281 282
282 m_host.ScheduleFullUpdate(); 283 m_host.ScheduleFullUpdate();
@@ -301,42 +302,19 @@ namespace OpenSim.Region.CoreModules.World.Sound
301 Vector3 position = part.AbsolutePosition; // region local 302 Vector3 position = part.AbsolutePosition; // region local
302 ulong regionHandle = m_scene.RegionInfo.RegionHandle; 303 ulong regionHandle = m_scene.RegionInfo.RegionHandle;
303 304
304 if (useMaster) 305 if(triggered)
305 { 306 TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius);
306 if (isMaster)
307 {
308 if (triggered)
309 TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius);
310 else
311 PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius);
312 part.ParentGroup.PlaySoundMasterPrim = part;
313 if (triggered)
314 TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius);
315 else
316 PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius);
317 foreach (SceneObjectPart prim in part.ParentGroup.PlaySoundSlavePrims)
318 {
319 position = prim.AbsolutePosition; // region local
320 if (triggered)
321 TriggerSound(soundID, part.OwnerID, prim.UUID, parentID, volume, position, regionHandle, radius);
322 else
323 PlayAttachedSound(soundID, part.OwnerID, prim.UUID, volume, position, flags, radius);
324 }
325 part.ParentGroup.PlaySoundSlavePrims.Clear();
326 part.ParentGroup.PlaySoundMasterPrim = null;
327 }
328 else
329 {
330 part.ParentGroup.PlaySoundSlavePrims.Add(part);
331 }
332 }
333 else 307 else
334 { 308 {
335 if (triggered) 309 byte bflags = 0;
336 TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius); 310
337 else 311 if (isMaster)
338 PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius); 312 bflags |= (byte)SoundFlags.SYNC_MASTER;
339 } 313 // TODO check viewer seems to accept both
314 if (useMaster)
315 bflags |= (byte)SoundFlags.SYNC_SLAVE;
316 PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, bflags, radius);
317 }
340 } 318 }
341 319
342 public void TriggerSoundLimited(UUID objectID, UUID sound, 320 public void TriggerSoundLimited(UUID objectID, UUID sound,
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Effects/ChannelDigger.cs b/OpenSim/Region/CoreModules/World/Terrain/Effects/ChannelDigger.cs
index 36917e9..b456aa1 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/Effects/ChannelDigger.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/Effects/ChannelDigger.cs
@@ -64,7 +64,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Effects
64 64
65 for (int i = 0; i < rounds; i++) 65 for (int i = 0; i < rounds; i++)
66 { 66 {
67 smoothFunction.FloodEffect(map, bitmap, 1.0); 67 smoothFunction.FloodEffect(map, bitmap, 1.0, 0, map.Width - 1, 0, map.Height - 1);
68 } 68 }
69 } 69 }
70 70
@@ -99,7 +99,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Effects
99 } 99 }
100 } 100 }
101 101
102 raiseFunction.FloodEffect(map, bitmap, height); 102 raiseFunction.FloodEffect(map, bitmap, height, 0, map.Width - 1, 0, map.Height - 1);
103 } 103 }
104 } 104 }
105 } 105 }
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Effects/CookieCutter.cs b/OpenSim/Region/CoreModules/World/Terrain/Effects/CookieCutter.cs
index dc76ad5..3222524 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/Effects/CookieCutter.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/Effects/CookieCutter.cs
@@ -84,7 +84,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Effects
84 for (y = 0; y < map.Height; y++) 84 for (y = 0; y < map.Height; y++)
85 { 85 {
86 if (cliffMask[x, y]) 86 if (cliffMask[x, y])
87 eroder.PaintEffect(map, allowMask, x, y, -1, 4, 0.1); 87 eroder.PaintEffect(map, allowMask, x, y, -1, 4, 0.1,0,map.Width - 1,0,map.Height - 1);
88 } 88 }
89 } 89 }
90 90
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs b/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs
index 89087b1..80396c4 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs
@@ -53,4 +53,4 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Effects
53 53
54 #endregion 54 #endregion
55 } 55 }
56} \ No newline at end of file 56}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/FlattenArea.cs b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/FlattenArea.cs
index 774e7b2..0c4171e 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/FlattenArea.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/FlattenArea.cs
@@ -33,15 +33,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
33 { 33 {
34 #region ITerrainFloodEffect Members 34 #region ITerrainFloodEffect Members
35 35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) 36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength,
37 int startX, int endX, int startY, int endY)
37 { 38 {
38 double sum = 0.0; 39 double sum = 0.0;
39 double steps = 0.0; 40 double steps = 0.0;
40 41
41 int x, y; 42 int x, y;
42 for (x = 0; x < map.Width; x++) 43 for (x = startX; x <= endX; x++)
43 { 44 {
44 for (y = 0; y < map.Height; y++) 45 for (y = startY; y <= endY; y++)
45 { 46 {
46 if (fillArea[x, y]) 47 if (fillArea[x, y])
47 { 48 {
@@ -55,9 +56,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
55 56
56 double str = 0.1 * strength; // == 0.2 in the default client 57 double str = 0.1 * strength; // == 0.2 in the default client
57 58
58 for (x = 0; x < map.Width; x++) 59 for (x = startX; x <= endX; x++)
59 { 60 {
60 for (y = 0; y < map.Height; y++) 61 for (y = startY; y <= endY; y++)
61 { 62 {
62 if (fillArea[x, y]) 63 if (fillArea[x, y])
63 map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str); 64 map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str);
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/LowerArea.cs b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/LowerArea.cs
index 3e87390..a275a86 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/LowerArea.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/LowerArea.cs
@@ -33,13 +33,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
33 { 33 {
34 #region ITerrainFloodEffect Members 34 #region ITerrainFloodEffect Members
35 35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) 36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength,
37 int startX, int endX, int startY, int endY)
37 { 38 {
38 int x; 39 int x,y;
39 for (x = 0; x < map.Width; x++) 40 for (x = startX; x <= endX; x++)
40 { 41 {
41 int y; 42 for (y = startY; y <= endY; y++)
42 for (y = 0; y < map.Height; y++)
43 { 43 {
44 if (fillArea[x, y]) 44 if (fillArea[x, y])
45 { 45 {
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/NoiseArea.cs b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/NoiseArea.cs
index b6c635c..d634e8b 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/NoiseArea.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/NoiseArea.cs
@@ -35,18 +35,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
35 { 35 {
36 #region ITerrainFloodEffect Members 36 #region ITerrainFloodEffect Members
37 37
38 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) 38 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength,
39 int startX, int endX, int startY, int endY)
39 { 40 {
40 int x; 41 int x, y;
41 for (x = 0; x < map.Width; x++) 42 for (x = startX; x <= endX; x++)
42 { 43 {
43 int y; 44 for (y = startY; y <= endY; y++)
44 for (y = 0; y < map.Height; y++)
45 { 45 {
46 if (fillArea[x, y]) 46 if (fillArea[x, y])
47 { 47 {
48 double noise = TerrainUtil.PerlinNoise2D((double) x / map.Width, (double) y / map.Height, 8, 1.0); 48 double noise = TerrainUtil.PerlinNoise2D((double) x / map.Width, (double) y / map.Height, 8, 1.0);
49
50 map[x, y] += noise * strength; 49 map[x, y] += noise * strength;
51 } 50 }
52 } 51 }
@@ -55,4 +54,4 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
55 54
56 #endregion 55 #endregion
57 } 56 }
58} \ No newline at end of file 57}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RaiseArea.cs b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RaiseArea.cs
index 3bdc5e7..6ccd5df 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RaiseArea.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RaiseArea.cs
@@ -33,13 +33,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
33 { 33 {
34 #region ITerrainFloodEffect Members 34 #region ITerrainFloodEffect Members
35 35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) 36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength,
37 int startX, int endX, int startY, int endY)
37 { 38 {
38 int x; 39 int x,y;
39 for (x = 0; x < map.Width; x++) 40 for (x = startX; x <= endX; x++)
40 { 41 {
41 int y; 42 for (y = startY; y <= endY; y++)
42 for (y = 0; y < map.Height; y++)
43 { 43 {
44 if (fillArea[x, y]) 44 if (fillArea[x, y])
45 { 45 {
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RevertArea.cs b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RevertArea.cs
index c5527fa..4230133 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RevertArea.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/RevertArea.cs
@@ -46,13 +46,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
46 /// <param name="map">the current heightmap</param> 46 /// <param name="map">the current heightmap</param>
47 /// <param name="fillArea">array indicating which sections of the map are to be reverted</param> 47 /// <param name="fillArea">array indicating which sections of the map are to be reverted</param>
48 /// <param name="strength">unused</param> 48 /// <param name="strength">unused</param>
49 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) 49 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength,
50 int startX, int endX, int startY, int endY)
50 { 51 {
51 int x; 52 int x, y;
52 for (x = 0; x < map.Width; x++) 53 for (x = startX; x <= endX; x++)
53 { 54 {
54 int y; 55 for (y = startY; y <= endY; y++)
55 for (y = 0; y < map.Height; y++)
56 { 56 {
57 if (fillArea[x, y]) 57 if (fillArea[x, y])
58 { 58 {
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/SmoothArea.cs b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/SmoothArea.cs
index 6b07747..6c0d60d 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/SmoothArea.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FloodBrushes/SmoothArea.cs
@@ -33,16 +33,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
33 { 33 {
34 #region ITerrainFloodEffect Members 34 #region ITerrainFloodEffect Members
35 35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) 36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength,
37 int startX, int endX, int startY, int endY)
37 { 38 {
38 double area = strength; 39 double area = strength;
39 double step = strength / 4.0; 40 double step = strength / 4.0;
40 41
41 double[,] manipulate = new double[map.Width,map.Height]; 42 double[,] manipulate = new double[map.Width,map.Height];
42 int x, y; 43 int x, y;
43 for (x = 0; x < map.Width; x++) 44 for (x = startX; x <= endX; x++)
44 { 45 {
45 for (y = 0; y < map.Height; y++) 46 for (y = startY; y <= endY; y++)
46 { 47 {
47 if (!fillArea[x, y]) 48 if (!fillArea[x, y])
48 continue; 49 continue;
@@ -64,9 +65,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FloodBrushes
64 manipulate[x, y] = average / avgsteps; 65 manipulate[x, y] = average / avgsteps;
65 } 66 }
66 } 67 }
67 for (x = 0; x < map.Width; x++) 68 for (x = startX; x <= endX; x++)
68 { 69 {
69 for (y = 0; y < map.Height; y++) 70 for (y = startY; y <= endY; y++)
70 { 71 {
71 if (!fillArea[x, y]) 72 if (!fillArea[x, y])
72 continue; 73 continue;
diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainFloodEffect.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainFloodEffect.cs
index 3984a30..6324aca 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/ITerrainFloodEffect.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainFloodEffect.cs
@@ -32,6 +32,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
32{ 32{
33 public interface ITerrainFloodEffect 33 public interface ITerrainFloodEffect
34 { 34 {
35 void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength); 35 void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength,
36 int startX, int endX, int startY, int endY);
36 } 37 }
37} \ No newline at end of file 38} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainPaintableEffect.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainPaintableEffect.cs
index b73defd..d0b05e4 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/ITerrainPaintableEffect.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainPaintableEffect.cs
@@ -31,6 +31,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
31{ 31{
32 public interface ITerrainPaintableEffect 32 public interface ITerrainPaintableEffect
33 { 33 {
34 void PaintEffect(ITerrainChannel map, bool[,] allowMask, double x, double y, double z, double strength, double duration); 34 void PaintEffect(ITerrainChannel map, bool[,] allowMask, double x, double y, double z,
35 double strength, double duration, int startX, int endX, int startY, int endY);
35 } 36 }
36} 37}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/ErodeSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/ErodeSphere.cs
index 7a78cd8..7358ba3 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/ErodeSphere.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/ErodeSphere.cs
@@ -151,7 +151,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
151 151
152 #region ITerrainPaintableEffect Members 152 #region ITerrainPaintableEffect Members
153 153
154 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) 154 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
155 double strength, double duration, int startX, int endX, int startY, int endY)
155 { 156 {
156 strength = TerrainUtil.MetersToSphericalStrength(strength); 157 strength = TerrainUtil.MetersToSphericalStrength(strength);
157 158
@@ -163,18 +164,23 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
163 ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height); 164 ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height);
164 165
165 // Fill with rain 166 // Fill with rain
166 for (x = 0; x < water.Width; x++) 167 for (x = startX; x <= endX; x++)
167 for (y = 0; y < water.Height; y++) 168 {
168 water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration); 169 for (y = startY; y <= endY; y++)
170 {
171 if (mask[x, y])
172 water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration);
173 }
174 }
169 175
170 for (int i = 0; i < rounds; i++) 176 for (int i = 0; i < rounds; i++)
171 { 177 {
172 // Erode underlying terrain 178 // Erode underlying terrain
173 for (x = 0; x < water.Width; x++) 179 for (x = startX; x <= endX; x++)
174 { 180 {
175 for (y = 0; y < water.Height; y++) 181 for (y = startY; y <= endY; y++)
176 { 182 {
177 if (mask[x,y]) 183 if (mask[x, y])
178 { 184 {
179 const double solConst = (1.0 / rounds); 185 const double solConst = (1.0 / rounds);
180 double sedDelta = water[x, y] * solConst; 186 double sedDelta = water[x, y] * solConst;
@@ -185,9 +191,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
185 } 191 }
186 192
187 // Move water 193 // Move water
188 for (x = 0; x < water.Width; x++) 194 for (x = startX; x <= endX; x++)
189 { 195 {
190 for (y = 0; y < water.Height; y++) 196 for (y = startY; y <= endY; y++)
191 { 197 {
192 if (water[x, y] <= 0) 198 if (water[x, y] <= 0)
193 continue; 199 continue;
@@ -296,7 +302,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
296 double sedimentDeposit = sediment[x, y] - waterCapacity; 302 double sedimentDeposit = sediment[x, y] - waterCapacity;
297 if (sedimentDeposit > 0) 303 if (sedimentDeposit > 0)
298 { 304 {
299 if (mask[x,y]) 305 if (mask[x, y])
300 { 306 {
301 sediment[x, y] -= sedimentDeposit; 307 sediment[x, y] -= sedimentDeposit;
302 map[x, y] += sedimentDeposit; 308 map[x, y] += sedimentDeposit;
@@ -309,10 +315,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
309 // Deposit any remainder (should be minimal) 315 // Deposit any remainder (should be minimal)
310 for (x = 0; x < water.Width; x++) 316 for (x = 0; x < water.Width; x++)
311 for (y = 0; y < water.Height; y++) 317 for (y = 0; y < water.Height; y++)
312 if (mask[x,y] && sediment[x, y] > 0) 318 if (mask[x, y] && sediment[x, y] > 0)
313 map[x, y] += sediment[x, y]; 319 map[x, y] += sediment[x, y];
314 } 320 }
315
316 #endregion 321 #endregion
317 } 322 }
318} 323}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/FlattenSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/FlattenSphere.cs
index 9aa3dff..8937f63 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/FlattenSphere.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/FlattenSphere.cs
@@ -35,16 +35,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
35 { 35 {
36 #region ITerrainPaintableEffect Members 36 #region ITerrainPaintableEffect Members
37 37
38 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) 38 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
39 double strength, double duration, int startX, int endX, int startY, int endY)
39 { 40 {
40 strength = TerrainUtil.MetersToSphericalStrength(strength); 41 strength = TerrainUtil.MetersToSphericalStrength(strength);
41 42
42 int x, y; 43 int x, y;
43 44
44 // blend in map 45 // blend in map
45 for (x = 0; x < map.Width; x++) 46 for (x = startX; x <= endX; x++)
46 { 47 {
47 for (y = 0; y < map.Height; y++) 48 for (y = startY; y <= endY; y++)
48 { 49 {
49 if (!mask[x,y]) 50 if (!mask[x,y])
50 continue; 51 continue;
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/LowerSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/LowerSphere.cs
index 68145f2..bbf9407 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/LowerSphere.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/LowerSphere.cs
@@ -34,34 +34,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
34 { 34 {
35 #region ITerrainPaintableEffect Members 35 #region ITerrainPaintableEffect Members
36 36
37 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) 37 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
38 double strength, double duration, int startX, int endX, int startY, int endY)
38 { 39 {
39 int s = (int) (Math.Pow(2, strength) + 0.5); 40 int s = (int) (Math.Pow(2, strength) + 0.5);
40 41
41 int x; 42 int x, y;
42 int xFrom = (int)(rx-s+0.5);
43 int xTo = (int)(rx+s+0.5) + 1;
44 int yFrom = (int)(ry-s+0.5);
45 int yTo = (int)(ry+s+0.5) + 1;
46 43
47 if (xFrom < 0) 44 for (x = startX; x <= endX; x++)
48 xFrom = 0;
49
50 if (yFrom < 0)
51 yFrom = 0;
52
53 if (xTo > map.Width)
54 xTo = map.Width;
55
56 if (yTo > map.Width)
57 yTo = map.Width;
58
59 for (x = xFrom; x < xTo; x++)
60 { 45 {
61 int y; 46 for (y = startY; y <= endY; y++)
62 for (y = yFrom; y < yTo; y++)
63 { 47 {
64 if (!mask[x,y]) 48 if (!mask[x, y])
65 continue; 49 continue;
66 50
67 // Calculate a cos-sphere and add it to the heighmap 51 // Calculate a cos-sphere and add it to the heighmap
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/NoiseSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/NoiseSphere.cs
index e7df3f8..46d47b4 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/NoiseSphere.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/NoiseSphere.cs
@@ -35,17 +35,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
35 { 35 {
36 #region ITerrainPaintableEffect Members 36 #region ITerrainPaintableEffect Members
37 37
38 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) 38 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
39 double strength, double duration, int startX, int endX, int startY, int endY)
39 { 40 {
40 strength = TerrainUtil.MetersToSphericalStrength(strength); 41 strength = TerrainUtil.MetersToSphericalStrength(strength);
41 42
42 int x; 43 int x, y;
43 for (x = 0; x < map.Width; x++) 44
45 for (x = startX; x <= endX; x++)
44 { 46 {
45 int y; 47 for (y = startY; y <= endY; y++)
46 for (y = 0; y < map.Height; y++)
47 { 48 {
48 if (!mask[x,y]) 49 if (!mask[x, y])
49 continue; 50 continue;
50 51
51 // Calculate a sphere and add it to the heighmap 52 // Calculate a sphere and add it to the heighmap
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/OlsenSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/OlsenSphere.cs
index b199df3..281690d 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/OlsenSphere.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/OlsenSphere.cs
@@ -152,18 +152,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
152 152
153 #region ITerrainPaintableEffect Members 153 #region ITerrainPaintableEffect Members
154 154
155 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) 155 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
156 double strength, double duration, int startX, int endX, int startY, int endY)
156 { 157 {
157 strength = TerrainUtil.MetersToSphericalStrength(strength); 158 strength = TerrainUtil.MetersToSphericalStrength(strength);
158 159
159 int x; 160 int x, y;
160 161
161 for (x = 0; x < map.Width; x++) 162 for (x = startX; x <= endX; x++)
162 { 163 {
163 int y; 164 for (y = startY; y <= endY; y++)
164 for (y = 0; y < map.Height; y++)
165 { 165 {
166 if (!mask[x,y]) 166 if (!mask[x, y])
167 continue; 167 continue;
168 168
169 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); 169 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RaiseSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RaiseSphere.cs
index bd9a8a0..1b704bb 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RaiseSphere.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RaiseSphere.cs
@@ -35,38 +35,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
35 #region ITerrainPaintableEffect Members 35 #region ITerrainPaintableEffect Members
36 36
37 37
38 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) 38 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
39 double strength, double duration, int startX, int endX, int startY, int endY)
39 { 40 {
40 int s = (int) (Math.Pow(2, strength) + 0.5); 41 int s = (int) (Math.Pow(2, strength) + 0.5);
41 42
42 int x; 43 int x,y;
43 int xFrom = (int)(rx-s+0.5);
44 int xTo = (int)(rx+s+0.5) + 1;
45 int yFrom = (int)(ry-s+0.5);
46 int yTo = (int)(ry+s+0.5) + 1;
47 44
48 if (xFrom < 0) 45 for (x = startX; x <= endX; x++)
49 xFrom = 0;
50
51 if (yFrom < 0)
52 yFrom = 0;
53
54 if (xTo > map.Width)
55 xTo = map.Width;
56
57 if (yTo > map.Width)
58 yTo = map.Width;
59
60 for (x = xFrom; x < xTo; x++)
61 { 46 {
62 int y; 47 for (y = startY; y <= endY; y++)
63 for (y = yFrom; y < yTo; y++)
64 { 48 {
65 if (!mask[x,y]) 49 if (!mask[x, y])
66 continue; 50 continue;
67 51
68 // Calculate a cos-sphere and add it to the heighmap 52 // Calculate a cos-sphere and add it to the heighmap
69 double r = Math.Sqrt((x-rx) * (x-rx) + ((y-ry) * (y-ry))); 53 double r = Math.Sqrt((x - rx) * (x - rx) + ((y - ry) * (y - ry)));
70 double z = Math.Cos(r * Math.PI / (s * 2)); 54 double z = Math.Cos(r * Math.PI / (s * 2));
71 if (z > 0.0) 55 if (z > 0.0)
72 map[x, y] += z * duration; 56 map[x, y] += z * duration;
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RevertSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RevertSphere.cs
index 4b28275..efc5324 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RevertSphere.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/RevertSphere.cs
@@ -41,7 +41,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
41 41
42 #region ITerrainPaintableEffect Members 42 #region ITerrainPaintableEffect Members
43 43
44 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) 44 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
45 double strength, double duration, int startX, int endX, int startY, int endY)
45 { 46 {
46 strength = TerrainUtil.MetersToSphericalStrength(strength); 47 strength = TerrainUtil.MetersToSphericalStrength(strength);
47 duration = 0.03; //MCP Should be read from ini file 48 duration = 0.03; //MCP Should be read from ini file
@@ -51,13 +52,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
51 if (duration < 0) 52 if (duration < 0)
52 return; 53 return;
53 54
54 int x; 55 int x,y;
55 for (x = 0; x < map.Width; x++) 56 for (x = startX; x <= endX; x++)
56 { 57 {
57 int y; 58 for (y = startY; y <= endY; y++)
58 for (y = 0; y < map.Height; y++)
59 { 59 {
60 if (!mask[x,y]) 60 if (!mask[x, y])
61 continue; 61 continue;
62 62
63 // Calculate a sphere and add it to the heighmap 63 // Calculate a sphere and add it to the heighmap
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/SmoothSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/SmoothSphere.cs
index 4834c86..65dd0a6 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/SmoothSphere.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/SmoothSphere.cs
@@ -34,7 +34,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
34 { 34 {
35 #region ITerrainPaintableEffect Members 35 #region ITerrainPaintableEffect Members
36 36
37 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) 37 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
38 double strength, double duration, int startX, int endX, int startY, int endY)
38 { 39 {
39 strength = TerrainUtil.MetersToSphericalStrength(strength); 40 strength = TerrainUtil.MetersToSphericalStrength(strength);
40 41
@@ -47,10 +48,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
47 48
48 49
49 // compute delta map 50 // compute delta map
50 for (x = 0; x < map.Width; x++) 51 for (x = startX; x <= endX; x++)
51 { 52 {
52 for (y = 0; y < map.Height; y++) 53 for (y = startY; y <= endY; y++)
53 { 54 {
55 if (!mask[x, y])
56 continue;
57
54 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); 58 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
55 59
56 if (z > 0) // add in non-zero amount 60 if (z > 0) // add in non-zero amount
@@ -73,11 +77,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
73 } 77 }
74 } 78 }
75 // blend in map 79 // blend in map
76 for (x = 0; x < map.Width; x++) 80 for (x = startX; x <= endX; x++)
77 { 81 {
78 for (y = 0; y < map.Height; y++) 82 for (y = startY; y <= endY; y++)
79 { 83 {
80 if (!mask[x,y]) 84 if (!mask[x, y])
81 continue; 85 continue;
82 86
83 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); 87 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
diff --git a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/WeatherSphere.cs b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/WeatherSphere.cs
index f31c8b6..f52fe07 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/WeatherSphere.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/PaintBrushes/WeatherSphere.cs
@@ -148,16 +148,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain.PaintBrushes
148 148
149 #region ITerrainPaintableEffect Members 149 #region ITerrainPaintableEffect Members
150 150
151 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration) 151 public void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz,
152 double strength, double duration, int startX, int endX, int startY, int endY)
152 { 153 {
153 strength = TerrainUtil.MetersToSphericalStrength(strength); 154 strength = TerrainUtil.MetersToSphericalStrength(strength);
154 155
155 int x; 156 int x,y;
156 157
157 for (x = 0; x < map.Width; x++) 158 for (x = startX; x <= endX; x++)
158 { 159 {
159 int y; 160 for (y = startY; y <= endY; y++)
160 for (y = 0; y < map.Height; y++)
161 { 161 {
162 if (!mask[x,y]) 162 if (!mask[x,y])
163 continue; 163 continue;
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 932652c..22723fc 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -86,14 +86,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain
86 private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>(); 86 private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>();
87 private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = 87 private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects =
88 new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); 88 new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>();
89
89 private Dictionary<string, ITerrainEffect> m_plugineffects; 90 private Dictionary<string, ITerrainEffect> m_plugineffects;
90 private Dictionary<string, ITerrainModifier> m_modifyOperations =
91 new Dictionary<string, ITerrainModifier>();
92 private ITerrainChannel m_channel; 91 private ITerrainChannel m_channel;
93 private ITerrainChannel m_revert; 92 private ITerrainChannel m_baked;
94 private Scene m_scene; 93 private Scene m_scene;
95 private volatile bool m_tainted; 94 private volatile bool m_tainted;
96 private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5); 95
97 private String m_InitialTerrain = "pinhead-island"; 96 private String m_InitialTerrain = "pinhead-island";
98 97
99 // If true, send terrain patch updates to clients based on their view distance 98 // If true, send terrain patch updates to clients based on their view distance
@@ -107,13 +106,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
107 private bool[,] updated; // for each patch, whether it needs to be sent to this client 106 private bool[,] updated; // for each patch, whether it needs to be sent to this client
108 private int updateCount; // number of patches that need to be sent 107 private int updateCount; // number of patches that need to be sent
109 public ScenePresence Presence; // a reference to the client to send to 108 public ScenePresence Presence; // a reference to the client to send to
110 public TerrainData Terrain; // reference to the underlying terrain 109
111 public PatchUpdates(TerrainData terrData, ScenePresence pPresence) 110 public PatchUpdates(TerrainData terrData, ScenePresence pPresence)
112 { 111 {
113 updated = new bool[terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize]; 112 updated = new bool[terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize];
114 updateCount = 0; 113 updateCount = 0;
115 Presence = pPresence; 114 Presence = pPresence;
116 Terrain = terrData;
117 // Initially, send all patches to the client 115 // Initially, send all patches to the client
118 SetAll(true); 116 SetAll(true);
119 } 117 }
@@ -146,12 +144,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain
146 public void SetAll(bool state) 144 public void SetAll(bool state)
147 { 145 {
148 updateCount = 0; 146 updateCount = 0;
149 for(int xx = 0; xx < updated.GetLength(0); xx++) 147 for (int xx = 0; xx < updated.GetLength(0); xx++)
150 for(int yy = 0; yy < updated.GetLength(1); yy++) 148 for (int yy = 0; yy < updated.GetLength(1); yy++)
151 updated[xx, yy] = state; 149 updated[xx, yy] = state;
152 if (state) 150 if (state)
153 updateCount = updated.GetLength(0) * updated.GetLength(1); 151 updateCount = updated.GetLength(0) * updated.GetLength(1);
154 } 152 }
153
155 // Logically OR's the terrain data's patch taint map into this client's update map. 154 // Logically OR's the terrain data's patch taint map into this client's update map.
156 public void SetAll(TerrainData terrData) 155 public void SetAll(TerrainData terrData)
157 { 156 {
@@ -164,9 +163,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
164 terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize) 163 terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize)
165 ); 164 );
166 } 165 }
167 for(int xx = 0; xx < terrData.SizeX; xx += Constants.TerrainPatchSize) 166
167 for (int xx = 0; xx < terrData.SizeX; xx += Constants.TerrainPatchSize)
168 { 168 {
169 for(int yy = 0; yy < terrData.SizeY; yy += Constants.TerrainPatchSize) 169 for (int yy = 0; yy < terrData.SizeY; yy += Constants.TerrainPatchSize)
170 { 170 {
171 // Only set tainted. The patch bit may be set if the patch was to be sent later. 171 // Only set tainted. The patch bit may be set if the patch was to be sent later.
172 if (terrData.IsTaintedAt(xx, yy, false)) 172 if (terrData.IsTaintedAt(xx, yy, false))
@@ -227,12 +227,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain
227 (int)m_scene.RegionInfo.RegionSizeY, 227 (int)m_scene.RegionInfo.RegionSizeY,
228 (int)m_scene.RegionInfo.RegionSizeZ); 228 (int)m_scene.RegionInfo.RegionSizeZ);
229 m_scene.Heightmap = m_channel; 229 m_scene.Heightmap = m_channel;
230 UpdateRevertMap(); 230
231 UpdateBakedMap();
231 } 232 }
232 else 233 else
233 { 234 {
234 m_channel = m_scene.Heightmap; 235 m_channel = m_scene.Heightmap;
235 UpdateRevertMap(); 236 UpdateBakedMap();
236 } 237 }
237 238
238 m_scene.RegisterModuleInterface<ITerrainModule>(this); 239 m_scene.RegisterModuleInterface<ITerrainModule>(this);
@@ -240,7 +241,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
240 m_scene.EventManager.OnClientClosed += EventManager_OnClientClosed; 241 m_scene.EventManager.OnClientClosed += EventManager_OnClientClosed;
241 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; 242 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
242 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick; 243 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick;
243 m_scene.EventManager.OnFrame += EventManager_OnFrame; 244 m_scene.EventManager.OnTerrainCheckUpdates += EventManager_TerrainCheckUpdates;
244 } 245 }
245 246
246 InstallDefaultEffects(); 247 InstallDefaultEffects();
@@ -279,7 +280,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
279 // remove the commands 280 // remove the commands
280 m_scene.UnregisterModuleCommander(m_commander.Name); 281 m_scene.UnregisterModuleCommander(m_commander.Name);
281 // remove the event-handlers 282 // remove the event-handlers
282 m_scene.EventManager.OnFrame -= EventManager_OnFrame; 283
284 m_scene.EventManager.OnTerrainCheckUpdates -= EventManager_TerrainCheckUpdates;
283 m_scene.EventManager.OnTerrainTick -= EventManager_OnTerrainTick; 285 m_scene.EventManager.OnTerrainTick -= EventManager_OnTerrainTick;
284 m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole; 286 m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole;
285 m_scene.EventManager.OnClientClosed -= EventManager_OnClientClosed; 287 m_scene.EventManager.OnClientClosed -= EventManager_OnClientClosed;
@@ -334,7 +336,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
334 m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height); 336 m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height);
335 m_scene.Heightmap = channel; 337 m_scene.Heightmap = channel;
336 m_channel = channel; 338 m_channel = channel;
337 UpdateRevertMap(); 339 UpdateBakedMap();
338 } 340 }
339 catch(NotImplementedException) 341 catch(NotImplementedException)
340 { 342 {
@@ -426,7 +428,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
426 { 428 {
427 ITerrainChannel channel = loader.Value.LoadStream(stream); 429 ITerrainChannel channel = loader.Value.LoadStream(stream);
428 m_channel.Merge(channel, displacement, radianRotation, rotationDisplacement); 430 m_channel.Merge(channel, displacement, radianRotation, rotationDisplacement);
429 UpdateRevertMap(); 431 UpdateBakedMap();
430 } 432 }
431 catch(NotImplementedException) 433 catch(NotImplementedException)
432 { 434 {
@@ -506,12 +508,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
506 508
507 // Someone diddled terrain outside the normal code paths. Set the taintedness for all clients. 509 // Someone diddled terrain outside the normal code paths. Set the taintedness for all clients.
508 // ITerrainModule.TaintTerrain() 510 // ITerrainModule.TaintTerrain()
509 public void TaintTerrain() 511 public void TaintTerrain ()
510 { 512 {
511 lock(m_perClientPatchUpdates) 513 lock (m_perClientPatchUpdates)
512 { 514 {
513 // Set the flags for all clients so the tainted patches will be sent out 515 // Set the flags for all clients so the tainted patches will be sent out
514 foreach(PatchUpdates pups in m_perClientPatchUpdates.Values) 516 foreach (PatchUpdates pups in m_perClientPatchUpdates.Values)
515 { 517 {
516 pups.SetAll(m_scene.Heightmap.GetTerrainData()); 518 pups.SetAll(m_scene.Heightmap.GetTerrainData());
517 } 519 }
@@ -521,32 +523,23 @@ namespace OpenSim.Region.CoreModules.World.Terrain
521 // ITerrainModule.PushTerrain() 523 // ITerrainModule.PushTerrain()
522 public void PushTerrain(IClientAPI pClient) 524 public void PushTerrain(IClientAPI pClient)
523 { 525 {
524 // If view distance based, set the modified patch bits and the frame event will send the updates 526 ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId);
525 if (m_sendTerrainUpdatesByViewDistance) 527 if (presence != null)
526 { 528 {
527 ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId); 529 lock (m_perClientPatchUpdates)
528 if (presence != null)
529 { 530 {
530 lock(m_perClientPatchUpdates) 531 PatchUpdates pups;
532 if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups))
531 { 533 {
532 PatchUpdates pups; 534 // There is a ScenePresence without a send patch map. Create one.
533 if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups)) 535 pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence);
534 { 536 m_perClientPatchUpdates.Add(presence.UUID, pups);
535 // There is a ScenePresence without a send patch map. Create one.
536 pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence);
537 m_perClientPatchUpdates.Add(presence.UUID, pups);
538 }
539 // By setting all to modified, the next update tick will send the patches
540 pups.SetAll(true);
541 } 537 }
538 pups.SetAll(true);
542 } 539 }
543 } 540 }
544 else
545 {
546 // The traditional way is to call into the protocol stack to send them all.
547 pClient.SendLayerData(new float[10]);
548 }
549 } 541 }
542
550 #region Plugin Loading Methods 543 #region Plugin Loading Methods
551 544
552 private void LoadPlugins() 545 private void LoadPlugins()
@@ -636,7 +629,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
636 m_painteffects[StandardTerrainEffects.Smooth] = new SmoothSphere(); 629 m_painteffects[StandardTerrainEffects.Smooth] = new SmoothSphere();
637 m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere(); 630 m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere();
638 m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere(); 631 m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere();
639 m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_revert); 632 m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_baked);
640 m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere(); 633 m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere();
641 m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere(); 634 m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere();
642 m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere(); 635 m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere();
@@ -647,9 +640,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
647 m_floodeffects[StandardTerrainEffects.Smooth] = new SmoothArea(); 640 m_floodeffects[StandardTerrainEffects.Smooth] = new SmoothArea();
648 m_floodeffects[StandardTerrainEffects.Noise] = new NoiseArea(); 641 m_floodeffects[StandardTerrainEffects.Noise] = new NoiseArea();
649 m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea(); 642 m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea();
650 m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert); 643 m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_baked);
651 644
652 // Terrain Modifier operations 645 // Terrain Modifier operations
646/*
653 m_modifyOperations["min"] = new MinModifier(this); 647 m_modifyOperations["min"] = new MinModifier(this);
654 m_modifyOperations["max"] = new MaxModifier(this); 648 m_modifyOperations["max"] = new MaxModifier(this);
655 m_modifyOperations["raise"] = new RaiseModifier(this); 649 m_modifyOperations["raise"] = new RaiseModifier(this);
@@ -657,7 +651,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
657 m_modifyOperations["fill"] = new FillModifier(this); 651 m_modifyOperations["fill"] = new FillModifier(this);
658 m_modifyOperations["smooth"] = new SmoothModifier(this); 652 m_modifyOperations["smooth"] = new SmoothModifier(this);
659 m_modifyOperations["noise"] = new NoiseModifier(this); 653 m_modifyOperations["noise"] = new NoiseModifier(this);
660 654*/
661 // Filesystem load/save loaders 655 // Filesystem load/save loaders
662 m_loaders[".r32"] = new RAW32(); 656 m_loaders[".r32"] = new RAW32();
663 m_loaders[".f32"] = m_loaders[".r32"]; 657 m_loaders[".f32"] = m_loaders[".r32"];
@@ -673,22 +667,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
673 } 667 }
674 668
675 /// <summary> 669 /// <summary>
676 /// Saves the current state of the region into the revert map buffer. 670 /// Saves the current state of the region into the baked map buffer.
671
677 /// </summary> 672 /// </summary>
678 public void UpdateRevertMap() 673 public void UpdateBakedMap()
679 { 674 {
680 /* 675 m_baked = m_channel.MakeCopy();
681 int x; 676 m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_baked);
682 for (x = 0; x < m_channel.Width; x++) 677 m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_baked);
683 {
684 int y;
685 for (y = 0; y < m_channel.Height; y++)
686 {
687 m_revert[x, y] = m_channel[x, y];
688 }
689 }
690 */
691 m_revert = m_channel.MakeCopy();
692 } 678 }
693 679
694 /// <summary> 680 /// <summary>
@@ -715,11 +701,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
715 { 701 {
716 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, 702 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY,
717 fileWidth, fileHeight, 703 fileWidth, fileHeight,
718 (int)m_scene.RegionInfo.RegionSizeX, 704 (int) m_scene.RegionInfo.RegionSizeX,
719 (int)m_scene.RegionInfo.RegionSizeY); 705 (int) m_scene.RegionInfo.RegionSizeY);
720 m_scene.Heightmap = channel; 706 m_scene.Heightmap = channel;
721 m_channel = channel; 707 m_channel = channel;
722 UpdateRevertMap(); 708 UpdateBakedMap();
723 } 709 }
724 710
725 return; 711 return;
@@ -782,22 +768,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain
782 } 768 }
783 769
784 /// <summary> 770 /// <summary>
785 /// Called before processing of every simulation frame.
786 /// This is used to check to see of any of the terrain is tainted and, if so, schedule 771 /// This is used to check to see of any of the terrain is tainted and, if so, schedule
787 /// updates for all the presences. 772 /// updates for all the presences.
788 /// This also checks to see if there are updates that need to be sent for each presence. 773 /// This also checks to see if there are updates that need to be sent for each presence.
789 /// This is where the logic is to send terrain updates to clients. 774 /// This is where the logic is to send terrain updates to clients.
790 /// </summary> 775 /// </summary>
791 private void EventManager_OnFrame() 776 private void EventManager_TerrainCheckUpdates()
792 { 777 {
778 // this needs fixing
793 TerrainData terrData = m_channel.GetTerrainData(); 779 TerrainData terrData = m_channel.GetTerrainData();
794 780
795 bool shouldTaint = false; 781 bool shouldTaint = false;
796 for(int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize) 782 for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize)
797 { 783 {
798 for(int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize) 784 for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize)
799 { 785 {
800 if (terrData.IsTaintedAt(x, y)) 786 if (terrData.IsTaintedAt(x, y,true))
801 { 787 {
802 // Found a patch that was modified. Push this flag into the clients. 788 // Found a patch that was modified. Push this flag into the clients.
803 SendToClients(terrData, x, y); 789 SendToClients(terrData, x, y);
@@ -883,11 +869,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
883 presence.ControllingClient.OnLandUndo -= client_OnLandUndo; 869 presence.ControllingClient.OnLandUndo -= client_OnLandUndo;
884 presence.ControllingClient.OnUnackedTerrain -= client_OnUnackedTerrain; 870 presence.ControllingClient.OnUnackedTerrain -= client_OnUnackedTerrain;
885 } 871 }
886 872 lock (m_perClientPatchUpdates)
887 lock(m_perClientPatchUpdates)
888 m_perClientPatchUpdates.Remove(client); 873 m_perClientPatchUpdates.Remove(client);
889 } 874 }
890 875
891 /// <summary> 876 /// <summary>
892 /// Scan over changes in the terrain and limit height changes. This enforces the 877 /// Scan over changes in the terrain and limit height changes. This enforces the
893 /// non-estate owner limits on rate of terrain editting. 878 /// non-estate owner limits on rate of terrain editting.
@@ -898,12 +883,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
898 TerrainData terrData = m_channel.GetTerrainData(); 883 TerrainData terrData = m_channel.GetTerrainData();
899 884
900 bool wasLimited = false; 885 bool wasLimited = false;
901 for(int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize) 886 for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize)
902 { 887 {
903 for(int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize) 888 for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize)
904 { 889 {
905 if (terrData.IsTaintedAt(x, y, false /* clearOnTest */)) 890 if (terrData.IsTaintedAt(x, y, false /* clearOnTest */))
906 { 891 {
907 // If we should respect the estate settings then 892 // If we should respect the estate settings then
908 // fixup and height deltas that don't respect them. 893 // fixup and height deltas that don't respect them.
909 // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values. 894 // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values.
@@ -926,13 +911,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain
926 float maxDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainRaiseLimit; 911 float maxDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainRaiseLimit;
927 912
928 // loop through the height map for this patch and compare it against 913 // loop through the height map for this patch and compare it against
929 // the revert map 914 // the baked map
930 for(int x = xStart; x < xStart + Constants.TerrainPatchSize; x++) 915 for (int x = xStart; x < xStart + Constants.TerrainPatchSize; x++)
931 { 916 {
932 for(int y = yStart; y < yStart + Constants.TerrainPatchSize; y++) 917 for(int y = yStart; y < yStart + Constants.TerrainPatchSize; y++)
933 { 918 {
934 float requestedHeight = terrData[x, y]; 919 float requestedHeight = terrData[x, y];
935 float bakedHeight = (float)m_revert[x, y]; 920 float bakedHeight = (float)m_baked[x, y];
936 float requestedDelta = requestedHeight - bakedHeight; 921 float requestedDelta = requestedHeight - bakedHeight;
937 922
938 if (requestedDelta > maxDelta) 923 if (requestedDelta > maxDelta)
@@ -953,15 +938,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
953 938
954 private void client_OnLandUndo(IClientAPI client) 939 private void client_OnLandUndo(IClientAPI client)
955 { 940 {
956 lock(m_undo)
957 {
958 if (m_undo.Count > 0)
959 {
960 LandUndoState goback = m_undo.Pop();
961 if (goback != null)
962 goback.PlaybackState();
963 }
964 }
965 } 941 }
966 942
967 /// <summary> 943 /// <summary>
@@ -972,12 +948,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
972 /// <param name="y">The patch corner to send</param> 948 /// <param name="y">The patch corner to send</param>
973 private void SendToClients(TerrainData terrData, int x, int y) 949 private void SendToClients(TerrainData terrData, int x, int y)
974 { 950 {
975 if (m_sendTerrainUpdatesByViewDistance) 951 // Add that this patch needs to be sent to the accounting for each client.
952 lock (m_perClientPatchUpdates)
976 { 953 {
977 // Add that this patch needs to be sent to the accounting for each client. 954 m_scene.ForEachScenePresence(presence =>
978 lock(m_perClientPatchUpdates)
979 {
980 m_scene.ForEachScenePresence(presence =>
981 { 955 {
982 PatchUpdates thisClientUpdates; 956 PatchUpdates thisClientUpdates;
983 if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates)) 957 if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates))
@@ -988,22 +962,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
988 } 962 }
989 thisClientUpdates.SetByXY(x, y, true); 963 thisClientUpdates.SetByXY(x, y, true);
990 } 964 }
991 );
992 }
993 }
994 else
995 {
996 // Legacy update sending where the update is sent out as soon as noticed
997 // We know the actual terrain data that is passed is ignored so this passes a dummy heightmap.
998 //float[] heightMap = terrData.GetFloatsSerialized();
999 float[] heightMap = new float[10];
1000 m_scene.ForEachClient(
1001 delegate(IClientAPI controller)
1002 {
1003 controller.SendLayerData(x / Constants.TerrainPatchSize,
1004 y / Constants.TerrainPatchSize,
1005 heightMap);
1006 }
1007 ); 965 );
1008 } 966 }
1009 } 967 }
@@ -1013,14 +971,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1013 public int PatchX; 971 public int PatchX;
1014 public int PatchY; 972 public int PatchY;
1015 public float Dist; 973 public float Dist;
1016
1017 public PatchesToSend(int pX, int pY, float pDist) 974 public PatchesToSend(int pX, int pY, float pDist)
1018 { 975 {
1019 PatchX = pX; 976 PatchX = pX;
1020 PatchY = pY; 977 PatchY = pY;
1021 Dist = pDist; 978 Dist = pDist;
1022 } 979 }
1023
1024 public int CompareTo(PatchesToSend other) 980 public int CompareTo(PatchesToSend other)
1025 { 981 {
1026 return Dist.CompareTo(other.Dist); 982 return Dist.CompareTo(other.Dist);
@@ -1029,15 +985,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1029 985
1030 // Called each frame time to see if there are any patches to send to any of the 986 // Called each frame time to see if there are any patches to send to any of the
1031 // ScenePresences. 987 // ScenePresences.
1032 // We know this is only called if we are doing view distance patch sending so some
1033 // tests are not made.
1034 // Loop through all the per-client info and send any patches necessary. 988 // Loop through all the per-client info and send any patches necessary.
1035 private void CheckSendingPatchesToClients() 989 private void CheckSendingPatchesToClients()
1036 { 990 {
1037 lock(m_perClientPatchUpdates) 991 lock (m_perClientPatchUpdates)
1038 { 992 {
1039 foreach(PatchUpdates pups in m_perClientPatchUpdates.Values) 993 foreach (PatchUpdates pups in m_perClientPatchUpdates.Values)
1040 { 994 {
995 // throught acording to land queue free to send bytes
996 if (!pups.Presence.ControllingClient.CanSendLayerData())
997 continue;
998
1041 if (pups.HasUpdates()) 999 if (pups.HasUpdates())
1042 { 1000 {
1043 // There is something that could be sent to this client. 1001 // There is something that could be sent to this client.
@@ -1048,7 +1006,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1048 // LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName); 1006 // LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName);
1049 // Sort the patches to send by the distance from the presence 1007 // Sort the patches to send by the distance from the presence
1050 toSend.Sort(); 1008 toSend.Sort();
1051 /* old way that sent individual patches 1009 /*
1052 foreach (PatchesToSend pts in toSend) 1010 foreach (PatchesToSend pts in toSend)
1053 { 1011 {
1054 pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null); 1012 pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null);
@@ -1056,12 +1014,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1056 } 1014 }
1057 */ 1015 */
1058 1016
1059 // new way that sends all patches to the protocol so they can be sent in one block
1060 int[] xPieces = new int[toSend.Count]; 1017 int[] xPieces = new int[toSend.Count];
1061 int[] yPieces = new int[toSend.Count]; 1018 int[] yPieces = new int[toSend.Count];
1062 float[] patchPieces = new float[toSend.Count * 2]; 1019 float[] patchPieces = new float[toSend.Count * 2];
1063 int pieceIndex = 0; 1020 int pieceIndex = 0;
1064 foreach(PatchesToSend pts in toSend) 1021 foreach (PatchesToSend pts in toSend)
1065 { 1022 {
1066 patchPieces[pieceIndex++] = pts.PatchX; 1023 patchPieces[pieceIndex++] = pts.PatchX;
1067 patchPieces[pieceIndex++] = pts.PatchY; 1024 patchPieces[pieceIndex++] = pts.PatchY;
@@ -1073,69 +1030,94 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1073 } 1030 }
1074 } 1031 }
1075 1032
1076 // Compute a list of modified patches that are within our view distance.
1077 private List<PatchesToSend> GetModifiedPatchesInViewDistance(PatchUpdates pups) 1033 private List<PatchesToSend> GetModifiedPatchesInViewDistance(PatchUpdates pups)
1078 { 1034 {
1079 List<PatchesToSend> ret = new List<PatchesToSend>(); 1035 List<PatchesToSend> ret = new List<PatchesToSend>();
1080 1036
1037 int npatchs = 0;
1038
1081 ScenePresence presence = pups.Presence; 1039 ScenePresence presence = pups.Presence;
1082 if (presence == null) 1040 if (presence == null)
1083 return ret; 1041 return ret;
1084 1042
1085 Vector3 presencePos = presence.AbsolutePosition; 1043 float minz = presence.AbsolutePosition.Z;
1044 if (presence.CameraPosition.Z < minz)
1045 minz = presence.CameraPosition.Z;
1046
1047 // this limit should be max terrainheight + max draw
1048 if (minz > 1500f)
1049 return ret;
1050
1051 int DrawDistance = (int)presence.DrawDistance;
1086 1052
1087 // Before this distance check, the whole region just showed up. Adding the distance 1053 DrawDistance = DrawDistance / Constants.TerrainPatchSize;
1088 // check causes different things to happen for the current and adjacent regions.
1089 // So, to keep legacy views, if the region is legacy sized, don't do distance check.
1090 bool isLegacySizedRegion = pups.Terrain.SizeX == Constants.RegionSize && pups.Terrain.SizeY == Constants.RegionSize;
1091 bool shouldCheckViewDistance = m_sendTerrainUpdatesByViewDistance && !isLegacySizedRegion;
1092 1054
1093 int startX = 0; 1055 int testposX;
1094 int endX = (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize; 1056 int testposY;
1095 int startY = 0;
1096 int endY = (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize;
1097 1057
1098 // The following only reduces the size of area scanned for updates. Only significant for very large varregions. 1058 if (Math.Abs(presence.AbsolutePosition.X - presence.CameraPosition.X) > 30
1099 if (shouldCheckViewDistance) 1059 || Math.Abs(presence.AbsolutePosition.Y - presence.CameraPosition.Y) > 30)
1100 { 1060 {
1101 // Compute the area of patches within our draw distance 1061 testposX = (int)presence.CameraPosition.X / Constants.TerrainPatchSize;
1102 startX = (((int)(presencePos.X - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2; 1062 testposY = (int)presence.CameraPosition.Y / Constants.TerrainPatchSize;
1103 startX = Math.Max(startX, 0);
1104 startX = Math.Min(startX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize);
1105 startY = (((int)(presencePos.Y - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2;
1106 startY = Math.Max(startY, 0);
1107 startY = Math.Min(startY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize);
1108 endX = (((int)(presencePos.X + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2;
1109 endX = Math.Max(endX, 0);
1110 endX = Math.Min(endX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize);
1111 endY = (((int)(presencePos.Y + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2;
1112 endY = Math.Max(endY, 0);
1113 endY = Math.Min(endY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize);
1114 } 1063 }
1115 1064 else
1116 // m_log.DebugFormat("{0} GetModifiedPatchesInViewDistance. rName={1}, ddist={2}, apos={3}, cpos={4}, isChild={5}, start=<{6},{7}>, end=<{8},{9}>",
1117 // LogHeader, m_scene.RegionInfo.RegionName,
1118 // presence.DrawDistance, presencePos, presence.CameraPosition,
1119 // isLegacySizeChildRegion,
1120 // startX, startY, endX, endY);
1121 for(int x = startX; x < endX; x++)
1122 { 1065 {
1123 for(int y = startY; y < endY; y++) 1066 testposX = (int)presence.AbsolutePosition.X / Constants.TerrainPatchSize;
1067 testposY = (int)presence.AbsolutePosition.Y / Constants.TerrainPatchSize;
1068 }
1069 int limitX = (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize;
1070 int limitY = (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize;
1071
1072 // Compute the area of patches within our draw distance
1073 int startX = testposX - DrawDistance;
1074 if (startX < 0)
1075 startX = 0;
1076 else if (startX > limitX)
1077 startX = limitX;
1078
1079 int startY = testposY - DrawDistance;
1080 if (startY < 0)
1081 startY = 0;
1082 else if (startY > limitY)
1083 startY = limitY;
1084
1085 int endX = testposX + DrawDistance;
1086 if (endX < 0)
1087 endX = 0;
1088 else if (endX > limitX)
1089 endX = limitX;
1090
1091 int endY = testposY + DrawDistance;
1092 if (endY < 0)
1093 endY = 0;
1094 else if (endY > limitY)
1095 endY = limitY;
1096
1097 int distx;
1098 int disty;
1099 int distsq;
1100
1101 DrawDistance *= DrawDistance;
1102
1103 for (int x = startX; x < endX; x++)
1104 {
1105 for (int y = startY; y < endY; y++)
1124 { 1106 {
1125 //Need to make sure we don't send the same ones over and over
1126 Vector3 patchPos = new Vector3(x * Constants.TerrainPatchSize, y * Constants.TerrainPatchSize, presencePos.Z);
1127 if (pups.GetByPatch(x, y)) 1107 if (pups.GetByPatch(x, y))
1128 { 1108 {
1129 //Check which has less distance, camera or avatar position, both have to be done. 1109 distx = x - testposX;
1130 //Its not a radius, its a diameter and we add 50 so that it doesn't look like it cuts off 1110 disty = y - testposY;
1131 if (!shouldCheckViewDistance 1111 distsq = distx * distx + disty * disty;
1132 || Util.DistanceLessThan(presencePos, patchPos, presence.DrawDistance + 50) 1112 if (distsq < DrawDistance)
1133 || Util.DistanceLessThan(presence.CameraPosition, patchPos, presence.DrawDistance + 50))
1134 { 1113 {
1135 //They can see it, send it to them
1136 pups.SetByPatch(x, y, false); 1114 pups.SetByPatch(x, y, false);
1137 float dist = Vector3.DistanceSquared(presencePos, patchPos); 1115 ret.Add(new PatchesToSend(x, y, (float)distsq));
1138 ret.Add(new PatchesToSend(x, y, dist)); 1116 if (npatchs++ > 65536)
1117 {
1118 y = endY;
1119 x = endX;
1120 }
1139 } 1121 }
1140 } 1122 }
1141 } 1123 }
@@ -1161,31 +1143,42 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1161 int zx = (int)(west + 0.5); 1143 int zx = (int)(west + 0.5);
1162 int zy = (int)(north + 0.5); 1144 int zy = (int)(north + 0.5);
1163 1145
1164 int dx; 1146 int startX = zx - n;
1165 for(dx=-n; dx<=n; dx++) 1147 if (startX < 0)
1148 startX = 0;
1149
1150 int startY = zy - n;
1151 if (startY < 0)
1152 startY = 0;
1153
1154 int endX = zx + n;
1155 if (endX >= m_channel.Width)
1156 endX = m_channel.Width - 1;
1157 int endY = zy + n;
1158 if (endY >= m_channel.Height)
1159 endY = m_channel.Height - 1;
1160
1161 int x, y;
1162
1163 for (x = startX; x <= endX; x++)
1166 { 1164 {
1167 int dy; 1165 for (y = startY; y <= endY; y++)
1168 for(dy=-n; dy<=n; dy++)
1169 { 1166 {
1170 int x = zx + dx; 1167 if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x, y, 0)))
1171 int y = zy + dy;
1172 if (x >= 0 && y >= 0 && x < m_channel.Width && y < m_channel.Height)
1173 { 1168 {
1174 if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x, y, 0))) 1169 allowMask[x, y] = true;
1175 { 1170 allowed = true;
1176 allowMask[x, y] = true;
1177 allowed = true;
1178 }
1179 } 1171 }
1180 } 1172 }
1181 } 1173 }
1182 if (allowed) 1174 if (allowed)
1183 { 1175 {
1184 StoreUndoState(); 1176 StoreUndoState();
1185 m_painteffects[(StandardTerrainEffects)action].PaintEffect( 1177 m_painteffects[(StandardTerrainEffects) action].PaintEffect(
1186 m_channel, allowMask, west, south, height, size, seconds); 1178 m_channel, allowMask, west, south, height, size, seconds,
1179 startX, endX, startY, endY);
1187 1180
1188 //revert changes outside estate limits 1181 //block changes outside estate limits
1189 if (!god) 1182 if (!god)
1190 EnforceEstateLimits(); 1183 EnforceEstateLimits();
1191 } 1184 }
@@ -1202,22 +1195,42 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1202 bool[,] fillArea = new bool[m_channel.Width, m_channel.Height]; 1195 bool[,] fillArea = new bool[m_channel.Width, m_channel.Height];
1203 fillArea.Initialize(); 1196 fillArea.Initialize();
1204 1197
1205 int x; 1198 int startX = (int)west;
1206 for(x = 0; x < m_channel.Width; x++) 1199 int startY = (int)south;
1200 int endX = (int)east;
1201 int endY = (int)north;
1202
1203 if (startX < 0)
1204 startX = 0;
1205 else if (startX >= m_channel.Width)
1206 startX = m_channel.Width - 1;
1207
1208 if (endX < 0)
1209 endX = 0;
1210 else if (endX >= m_channel.Width)
1211 endX = m_channel.Width - 1;
1212
1213 if (startY < 0)
1214 startY = 0;
1215 else if (startY >= m_channel.Height)
1216 startY = m_channel.Height - 1;
1217
1218 if (endY < 0)
1219 endY = 0;
1220 else if (endY >= m_channel.Height)
1221 endY = m_channel.Height - 1;
1222
1223
1224 int x, y;
1225
1226 for (x = startX; x <= endX; x++)
1207 { 1227 {
1208 int y; 1228 for (y = startY; y <= endY; y++)
1209 for(y = 0; y < m_channel.Height; y++)
1210 { 1229 {
1211 if (x < east && x > west) 1230 if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x, y, 0)))
1212 { 1231 {
1213 if (y < north && y > south) 1232 fillArea[x, y] = true;
1214 { 1233 allowed = true;
1215 if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x, y, 0)))
1216 {
1217 fillArea[x, y] = true;
1218 allowed = true;
1219 }
1220 }
1221 } 1234 }
1222 } 1235 }
1223 } 1236 }
@@ -1225,9 +1238,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1225 if (allowed) 1238 if (allowed)
1226 { 1239 {
1227 StoreUndoState(); 1240 StoreUndoState();
1228 m_floodeffects[(StandardTerrainEffects)action].FloodEffect(m_channel, fillArea, size); 1241 m_floodeffects[(StandardTerrainEffects)action].FloodEffect(m_channel, fillArea, size,
1242 startX, endX, startY, endY);
1229 1243
1230 //revert changes outside estate limits 1244 //block changes outside estate limits
1231 if (!god) 1245 if (!god)
1232 EnforceEstateLimits(); 1246 EnforceEstateLimits();
1233 } 1247 }
@@ -1260,37 +1274,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1260 1274
1261 private void StoreUndoState() 1275 private void StoreUndoState()
1262 { 1276 {
1263 lock(m_undo)
1264 {
1265 if (m_undo.Count > 0)
1266 {
1267 LandUndoState last = m_undo.Peek();
1268 if (last != null)
1269 {
1270 if (last.Compare(m_channel))
1271 return;
1272 }
1273 }
1274
1275 LandUndoState nUndo = new LandUndoState(this, m_channel);
1276 m_undo.Push(nUndo);
1277 }
1278 } 1277 }
1279 1278
1280 #region Console Commands 1279 #region Console Commands
1281 1280
1282 private void InterfaceLoadFile(Object[] args) 1281 private void InterfaceLoadFile(Object[] args)
1283 { 1282 {
1284 LoadFromFile((string)args[0]); 1283 LoadFromFile((string) args[0]);
1285 } 1284 }
1286 1285
1287 private void InterfaceLoadTileFile(Object[] args) 1286 private void InterfaceLoadTileFile(Object[] args)
1288 { 1287 {
1289 LoadFromFile((string)args[0], 1288 LoadFromFile((string) args[0],
1290 (int)args[1], 1289 (int) args[1],
1291 (int)args[2], 1290 (int) args[2],
1292 (int)args[3], 1291 (int) args[3],
1293 (int)args[4]); 1292 (int) args[4]);
1294 } 1293 }
1295 1294
1296 private void InterfaceSaveFile(Object[] args) 1295 private void InterfaceSaveFile(Object[] args)
@@ -1309,15 +1308,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1309 1308
1310 private void InterfaceBakeTerrain(Object[] args) 1309 private void InterfaceBakeTerrain(Object[] args)
1311 { 1310 {
1312 UpdateRevertMap(); 1311 UpdateBakedMap();
1313 } 1312 }
1314 1313
1315 private void InterfaceRevertTerrain(Object[] args) 1314 private void InterfaceRevertTerrain(Object[] args)
1316 { 1315 {
1317 int x, y; 1316 int x, y;
1318 for(x = 0; x < m_channel.Width; x++) 1317 for (x = 0; x < m_channel.Width; x++)
1319 for(y = 0; y < m_channel.Height; y++) 1318 for (y = 0; y < m_channel.Height; y++)
1320 m_channel[x, y] = m_revert[x, y]; 1319 m_channel[x, y] = m_baked[x, y];
1321 1320
1322 } 1321 }
1323 1322
@@ -1327,9 +1326,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1327 1326
1328 if (direction.ToLower().StartsWith("y")) 1327 if (direction.ToLower().StartsWith("y"))
1329 { 1328 {
1330 for(int x = 0; x < m_channel.Width; x++) 1329 for (int x = 0; x < m_channel.Width; x++)
1331 { 1330 {
1332 for(int y = 0; y < m_channel.Height / 2; y++) 1331 for (int y = 0; y < m_channel.Height / 2; y++)
1333 { 1332 {
1334 double height = m_channel[x, y]; 1333 double height = m_channel[x, y];
1335 double flippedHeight = m_channel[x, (int)m_channel.Height - 1 - y]; 1334 double flippedHeight = m_channel[x, (int)m_channel.Height - 1 - y];
@@ -1341,9 +1340,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1341 } 1340 }
1342 else if (direction.ToLower().StartsWith("x")) 1341 else if (direction.ToLower().StartsWith("x"))
1343 { 1342 {
1344 for(int y = 0; y < m_channel.Height; y++) 1343 for (int y = 0; y < m_channel.Height; y++)
1345 { 1344 {
1346 for(int x = 0; x < m_channel.Width / 2; x++) 1345 for (int x = 0; x < m_channel.Width / 2; x++)
1347 { 1346 {
1348 double height = m_channel[x, y]; 1347 double height = m_channel[x, y];
1349 double flippedHeight = m_channel[(int)m_channel.Width - 1 - x, y]; 1348 double flippedHeight = m_channel[(int)m_channel.Width - 1 - x, y];
@@ -1420,45 +1419,53 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1420 1419
1421 private void InterfaceElevateTerrain(Object[] args) 1420 private void InterfaceElevateTerrain(Object[] args)
1422 { 1421 {
1422 double val = (double)args[0];
1423
1423 int x, y; 1424 int x, y;
1424 for(x = 0; x < m_channel.Width; x++) 1425 for (x = 0; x < m_channel.Width; x++)
1425 for(y = 0; y < m_channel.Height; y++) 1426 for (y = 0; y < m_channel.Height; y++)
1426 m_channel[x, y] += (double)args[0]; 1427 m_channel[x, y] += val;
1427 } 1428 }
1428 1429
1429 private void InterfaceMultiplyTerrain(Object[] args) 1430 private void InterfaceMultiplyTerrain(Object[] args)
1430 { 1431 {
1431 int x, y; 1432 int x, y;
1432 for(x = 0; x < m_channel.Width; x++) 1433 double val = (double)args[0];
1433 for(y = 0; y < m_channel.Height; y++) 1434
1434 m_channel[x, y] *= (double)args[0]; 1435 for (x = 0; x < m_channel.Width; x++)
1436 for (y = 0; y < m_channel.Height; y++)
1437 m_channel[x, y] *= val;
1435 } 1438 }
1436 1439
1437 private void InterfaceLowerTerrain(Object[] args) 1440 private void InterfaceLowerTerrain(Object[] args)
1438 { 1441 {
1439 int x, y; 1442 int x, y;
1440 for(x = 0; x < m_channel.Width; x++) 1443 double val = (double)args[0];
1441 for(y = 0; y < m_channel.Height; y++) 1444
1442 m_channel[x, y] -= (double)args[0]; 1445 for (x = 0; x < m_channel.Width; x++)
1446 for (y = 0; y < m_channel.Height; y++)
1447 m_channel[x, y] -= val;
1443 } 1448 }
1444 1449
1445 public void InterfaceFillTerrain(Object[] args) 1450 public void InterfaceFillTerrain(Object[] args)
1446 { 1451 {
1447 int x, y; 1452 int x, y;
1453 double val = (double)args[0];
1448 1454
1449 for(x = 0; x < m_channel.Width; x++) 1455 for (x = 0; x < m_channel.Width; x++)
1450 for(y = 0; y < m_channel.Height; y++) 1456 for (y = 0; y < m_channel.Height; y++)
1451 m_channel[x, y] = (double)args[0]; 1457 m_channel[x, y] = val;
1452 } 1458 }
1453 1459
1454 private void InterfaceMinTerrain(Object[] args) 1460 private void InterfaceMinTerrain(Object[] args)
1455 { 1461 {
1456 int x, y; 1462 int x, y;
1457 for(x = 0; x < m_channel.Width; x++) 1463 double val = (double)args[0];
1464 for (x = 0; x < m_channel.Width; x++)
1458 { 1465 {
1459 for(y = 0; y < m_channel.Height; y++) 1466 for(y = 0; y < m_channel.Height; y++)
1460 { 1467 {
1461 m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]); 1468 m_channel[x, y] = Math.Max(val, m_channel[x, y]);
1462 } 1469 }
1463 } 1470 }
1464 } 1471 }
@@ -1466,11 +1473,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1466 private void InterfaceMaxTerrain(Object[] args) 1473 private void InterfaceMaxTerrain(Object[] args)
1467 { 1474 {
1468 int x, y; 1475 int x, y;
1469 for(x = 0; x < m_channel.Width; x++) 1476 double val = (double)args[0];
1477 for (x = 0; x < m_channel.Width; x++)
1470 { 1478 {
1471 for(y = 0; y < m_channel.Height; y++) 1479 for(y = 0; y < m_channel.Height; y++)
1472 { 1480 {
1473 m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]); 1481 m_channel[x, y] = Math.Min(val, m_channel[x, y]);
1474 } 1482 }
1475 } 1483 }
1476 } 1484 }
@@ -1620,9 +1628,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1620 multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double"); 1628 multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double");
1621 1629
1622 Command bakeRegionCommand = 1630 Command bakeRegionCommand =
1623 new Command("bake", CommandIntentions.COMMAND_HAZARDOUS, InterfaceBakeTerrain, "Saves the current terrain into the regions revert map."); 1631 new Command("bake", CommandIntentions.COMMAND_HAZARDOUS, InterfaceBakeTerrain, "Saves the current terrain into the regions baked map.");
1624 Command revertRegionCommand = 1632 Command revertRegionCommand =
1625 new Command("revert", CommandIntentions.COMMAND_HAZARDOUS, InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap."); 1633 new Command("revert", CommandIntentions.COMMAND_HAZARDOUS, InterfaceRevertTerrain, "Loads the baked map terrain into the regions heightmap.");
1626 1634
1627 Command flipCommand = 1635 Command flipCommand =
1628 new Command("flip", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFlipTerrain, "Flips the current terrain about the X or Y axis"); 1636 new Command("flip", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFlipTerrain, "Flips the current terrain about the X or Y axis");
@@ -1699,6 +1707,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1699 1707
1700 public void ModifyCommand(string module, string[] cmd) 1708 public void ModifyCommand(string module, string[] cmd)
1701 { 1709 {
1710 /*
1702 string result; 1711 string result;
1703 Scene scene = SceneManager.Instance.CurrentScene; 1712 Scene scene = SceneManager.Instance.CurrentScene;
1704 if ((scene != null) && (scene != m_scene)) 1713 if ((scene != null) && (scene != m_scene))
@@ -1738,6 +1747,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1738 { 1747 {
1739 MainConsole.Instance.Output(result); 1748 MainConsole.Instance.Output(result);
1740 } 1749 }
1750 */
1741 } 1751 }
1742 1752
1743#endregion 1753#endregion
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs
index 29e80ef..b209b33 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs
@@ -60,7 +60,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests
60 TerrainChannel map = new TerrainChannel((int)Constants.RegionSize, (int)Constants.RegionSize); 60 TerrainChannel map = new TerrainChannel((int)Constants.RegionSize, (int)Constants.RegionSize);
61 ITerrainPaintableEffect effect = new RaiseSphere(); 61 ITerrainPaintableEffect effect = new RaiseSphere();
62 62
63 effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0); 63 effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0,
64 0, midRegion - 1,0, (int)Constants.RegionSize -1);
64 Assert.That(map[127, midRegion] > 0.0, "Raise brush should raising value at this point (127,128)."); 65 Assert.That(map[127, midRegion] > 0.0, "Raise brush should raising value at this point (127,128).");
65 Assert.That(map[125, midRegion] > 0.0, "Raise brush should raising value at this point (124,128)."); 66 Assert.That(map[125, midRegion] > 0.0, "Raise brush should raising value at this point (124,128).");
66 Assert.That(map[120, midRegion] == 0.0, "Raise brush should not change value at this point (120,128)."); 67 Assert.That(map[120, midRegion] == 0.0, "Raise brush should not change value at this point (120,128).");
@@ -79,7 +80,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests
79 } 80 }
80 effect = new LowerSphere(); 81 effect = new LowerSphere();
81 82
82 effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0); 83 effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0,
84 0, (int)Constants.RegionSize -1,0, (int)Constants.RegionSize -1);
83 Assert.That(map[127, midRegion] >= 0.0, "Lower should not lowering value below 0.0 at this point (127,128)."); 85 Assert.That(map[127, midRegion] >= 0.0, "Lower should not lowering value below 0.0 at this point (127,128).");
84 Assert.That(map[127, midRegion] == 0.0, "Lower brush should lowering value to 0.0 at this point (127,128)."); 86 Assert.That(map[127, midRegion] == 0.0, "Lower brush should lowering value to 0.0 at this point (127,128).");
85 Assert.That(map[125, midRegion] < 1.0, "Lower brush should lowering value at this point (124,128)."); 87 Assert.That(map[125, midRegion] < 1.0, "Lower brush should lowering value at this point (124,128).");
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs
index 9534ad3..4719ba3 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs
@@ -79,6 +79,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
79 /// <remarks>Based on the algorithm described at http://opensimulator.org/wiki/Terrain_Splatting 79 /// <remarks>Based on the algorithm described at http://opensimulator.org/wiki/Terrain_Splatting
80 /// Note we create a 256x256 dimension texture even if the actual terrain is larger. 80 /// Note we create a 256x256 dimension texture even if the actual terrain is larger.
81 /// </remarks> 81 /// </remarks>
82
82 public static Bitmap Splat(ITerrainChannel terrain, 83 public static Bitmap Splat(ITerrainChannel terrain,
83 UUID[] textureIDs, float[] startHeights, float[] heightRanges, 84 UUID[] textureIDs, float[] startHeights, float[] heightRanges,
84 Vector3d regionPosition, IAssetService assetService, bool textureTerrain) 85 Vector3d regionPosition, IAssetService assetService, bool textureTerrain)
@@ -129,8 +130,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
129 asset = assetService.Get(textureIDs[i].ToString()); 130 asset = assetService.Get(textureIDs[i].ToString());
130 if (asset != null) 131 if (asset != null)
131 { 132 {
132// m_log.DebugFormat( 133 // m_log.DebugFormat(
133// "[TERRAIN SPLAT]: Got cached original JPEG2000 terrain texture {0} {1}", i, asset.ID); 134 // "[TERRAIN SPLAT]: Got cached original JPEG2000 terrain texture {0} {1}", i, asset.ID);
134 135
135 try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } 136 try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); }
136 catch (Exception ex) 137 catch (Exception ex)
@@ -140,7 +141,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
140 } 141 }
141 142
142 if (detailTexture[i] != null) 143 if (detailTexture[i] != null)
143 { 144 {
144 // Make sure this texture is the correct size, otherwise resize 145 // Make sure this texture is the correct size, otherwise resize
145 if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256) 146 if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256)
146 { 147 {
@@ -352,7 +353,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
352 b.Dispose(); 353 b.Dispose();
353 return result; 354 return result;
354 } 355 }
355
356 public static Bitmap SplatSimple(float[] heightmap) 356 public static Bitmap SplatSimple(float[] heightmap)
357 { 357 {
358 const float BASE_HSV_H = 93f / 360f; 358 const float BASE_HSV_H = 93f / 360f;
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index 5f2534b..443eee1 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
@@ -80,6 +80,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
80 80
81 private bool m_Enabled = false; 81 private bool m_Enabled = false;
82 82
83 private Bitmap lastImage = null;
84 private DateTime lastImageTime = DateTime.MinValue;
85
83 #region Region Module interface 86 #region Region Module interface
84 87
85 public void Initialise(IConfigSource source) 88 public void Initialise(IConfigSource source)
@@ -118,14 +121,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
118 121
119 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 122 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
120 if (renderers.Count > 0) 123 if (renderers.Count > 0)
121 { 124 m_log.Info("[MAPTILE]: Loaded prim mesher " + renderers[0]);
122 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
123 m_log.DebugFormat("[WARP 3D IMAGE MODULE]: Loaded prim mesher {0}", m_primMesher);
124 }
125 else 125 else
126 { 126 m_log.Info("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled");
127 m_log.Debug("[WARP 3D IMAGE MODULE]: No prim mesher loaded, prim rendering will be disabled");
128 }
129 127
130 m_scene.RegisterModuleInterface<IMapImageGenerator>(this); 128 m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
131 } 129 }
@@ -158,18 +156,36 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
158 156
159 public Bitmap CreateMapTile() 157 public Bitmap CreateMapTile()
160 { 158 {
161 // Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f); 159 /* this must be on all map, not just its image
162 // Camera above the middle of the region 160 if ((DateTime.Now - lastImageTime).TotalSeconds < 3600)
161 {
162 return (Bitmap)lastImage.Clone();
163 }
164 */
165
166 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
167 if (renderers.Count > 0)
168 {
169 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
170 }
171
163 Vector3 camPos = new Vector3( 172 Vector3 camPos = new Vector3(
164 m_scene.RegionInfo.RegionSizeX/2 - 0.5f, 173 m_scene.RegionInfo.RegionSizeX / 2 - 0.5f,
165 m_scene.RegionInfo.RegionSizeY/2 - 0.5f, 174 m_scene.RegionInfo.RegionSizeY / 2 - 0.5f,
166 221.7025033688163f); 175 221.7025033688163f);
167 // Viewport viewing down onto the region 176 // Viewport viewing down onto the region
168 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, 177 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f,
169 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY, 178 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY,
170 (float)m_scene.RegionInfo.RegionSizeX, (float)m_scene.RegionInfo.RegionSizeY ); 179 (float)m_scene.RegionInfo.RegionSizeX, (float)m_scene.RegionInfo.RegionSizeY);
171 // Fill the viewport and return the image 180
172 return CreateMapTile(viewport, false); 181 Bitmap tile = CreateMapTile(viewport, false);
182 m_primMesher = null;
183 return tile;
184/*
185 lastImage = tile;
186 lastImageTime = DateTime.Now;
187 return (Bitmap)lastImage.Clone();
188 */
173 } 189 }
174 190
175 public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) 191 public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures)
@@ -285,9 +301,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
285 float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; 301 float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;
286 302
287 renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f); 303 renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f);
288 renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX/2 - 0.5f, 304 renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX / 2 - 0.5f,
289 waterHeight, 305 waterHeight,
290 m_scene.RegionInfo.RegionSizeY/2 - 0.5f ); 306 m_scene.RegionInfo.RegionSizeY / 2 - 0.5f);
291 307
292 warp_Material waterColorMaterial = new warp_Material(ConvertColor(WATER_COLOR)); 308 warp_Material waterColorMaterial = new warp_Material(ConvertColor(WATER_COLOR));
293 waterColorMaterial.setReflectivity(0); // match water color with standard map module thanks lkalif 309 waterColorMaterial.setReflectivity(0); // match water color with standard map module thanks lkalif
@@ -316,7 +332,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
316 warp_Vector pos = ConvertVector(x, y, (float)terrain[(int)x, (int)y]); 332 warp_Vector pos = ConvertVector(x, y, (float)terrain[(int)x, (int)y]);
317 obj.addVertex(new warp_Vertex(pos, 333 obj.addVertex(new warp_Vertex(pos,
318 x / (float)m_scene.RegionInfo.RegionSizeX, 334 x / (float)m_scene.RegionInfo.RegionSizeX,
319 (((float)m_scene.RegionInfo.RegionSizeY) - y) / m_scene.RegionInfo.RegionSizeY) ); 335 (((float)m_scene.RegionInfo.RegionSizeY) - y) / m_scene.RegionInfo.RegionSizeY));
320 } 336 }
321 } 337 }
322 338
@@ -384,7 +400,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
384 warp_Texture texture; 400 warp_Texture texture;
385 using ( 401 using (
386 Bitmap image 402 Bitmap image
387 = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges, 403 = TerrainSplat.Splat(
404 terrain, textureIDs, startHeights, heightRanges,
388 new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) 405 new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain))
389 { 406 {
390 texture = new warp_Texture(image); 407 texture = new warp_Texture(image);
@@ -660,7 +677,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
660 #endregion Rendering Methods 677 #endregion Rendering Methods
661 678
662 #region Static Helpers 679 #region Static Helpers
663
664 // Note: axis change. 680 // Note: axis change.
665 private static warp_Vector ConvertVector(float x, float y, float z) 681 private static warp_Vector ConvertVector(float x, float y, float z)
666 { 682 {
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index d862f18..e08bdc0 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -141,25 +141,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
141 141
142 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) 142 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
143 { 143 {
144 List<MapBlockData> blocks = new List<MapBlockData>(); 144 Util.FireAndForget(x =>
145 if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4))
146 { 145 {
147 // final block, closing the search result 146 List<MapBlockData> blocks = new List<MapBlockData>();
148 AddFinalBlock(blocks); 147 if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4))
148 {
149 // final block, closing the search result
150 AddFinalBlock(blocks);
149 151
150 // flags are agent flags sent from the viewer. 152 // flags are agent flags sent from the viewer.
151 // they have different values depending on different viewers, apparently 153 // they have different values depending on different viewers, apparently
152 remoteClient.SendMapBlock(blocks, flags); 154 remoteClient.SendMapBlock(blocks, flags);
153 remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); 155 remoteClient.SendAlertMessage("Use a search string with at least 3 characters");
154 return; 156 return;
155 } 157 }
156 158
159 //m_log.DebugFormat("MAP NAME=({0})", mapName);
157 160
158 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
159
160 string mapNameOrig = mapName;
161 if (regionInfos.Count == 0)
162 {
163 // Hack to get around the fact that ll V3 now drops the port from the 161 // Hack to get around the fact that ll V3 now drops the port from the
164 // map name. See https://jira.secondlife.com/browse/VWR-28570 162 // map name. See https://jira.secondlife.com/browse/VWR-28570
165 // 163 //
@@ -168,6 +166,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
168 // or url encode if possible. 166 // or url encode if possible.
169 // the hacks we do with this viewer... 167 // the hacks we do with this viewer...
170 // 168 //
169 string mapNameOrig = mapName;
171 if (mapName.Contains("|")) 170 if (mapName.Contains("|"))
172 mapName = mapName.Replace('|', ':'); 171 mapName = mapName.Replace('|', ':');
173 if (mapName.Contains("+")) 172 if (mapName.Contains("+"))
@@ -175,52 +174,70 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
175 if (mapName.Contains("!")) 174 if (mapName.Contains("!"))
176 mapName = mapName.Replace('!', '/'); 175 mapName = mapName.Replace('!', '/');
177 176
178 if (mapName != mapNameOrig) 177 // try to fetch from GridServer
179 regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); 178 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
180 } 179 // if (regionInfos.Count == 0)
181 180 // remoteClient.SendAlertMessage("Hyperlink could not be established.");
182 m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); 181
183 182 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
184 if (regionInfos.Count > 0) 183
185 { 184 MapBlockData data;
186 foreach (GridRegion info in regionInfos) 185 if (regionInfos.Count > 0)
187 { 186 {
188 if ((flags & 2) == 2) // V2 sends this 187 foreach (GridRegion info in regionInfos)
189 { 188 {
190 List<MapBlockData> datas = WorldMap.Map2BlockFromGridRegion(info, flags); 189 data = new MapBlockData();
190 data.Agents = 0;
191 data.Access = info.Access;
192 if (flags == 2) // V2 sends this
193 {
194 List<MapBlockData> datas = WorldMap.Map2BlockFromGridRegion(info, flags);
195 // ugh! V2-3 is very sensitive about the result being
196 // exactly the same as the requested name
197
198 if (regionInfos.Count == 1 && (mapName != mapNameOrig))
199 datas.ForEach(d => d.Name = mapNameOrig);
200
201 blocks.AddRange(datas);
202 }
203 else
204 {
205 MapBlockData block = new MapBlockData();
206 WorldMap.MapBlockFromGridRegion(block,info, flags);
207 blocks.Add(block);
208 }
191 // ugh! V2-3 is very sensitive about the result being 209 // ugh! V2-3 is very sensitive about the result being
192 // exactly the same as the requested name 210 // exactly the same as the requested name
193 if (regionInfos.Count == 1 && (mapName != mapNameOrig)) 211 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
194 datas.ForEach(d => d.Name = mapNameOrig); 212 data.Name = mapNameOrig;
195 213 else
196 blocks.AddRange(datas); 214 data.Name = info.RegionName;
197 } 215 data.RegionFlags = 0; // TODO not used?
198 else 216 data.WaterHeight = 0; // not used
199 { 217 data.X = (ushort)(info.RegionLocX / Constants.RegionSize);
200 MapBlockData data = WorldMap.MapBlockFromGridRegion(info, flags); 218 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize);
201 blocks.Add(data); 219 blocks.Add(data);
202 } 220 }
203 } 221 }
204 }
205 222
206 // final block, closing the search result 223 // final block, closing the search result
207 AddFinalBlock(blocks); 224 AddFinalBlock(blocks);
208 225
209 // flags are agent flags sent from the viewer. 226 // flags are agent flags sent from the viewer.
210 // they have different values depending on different viewers, apparently 227 // they have different values depending on different viewers, apparently
211 remoteClient.SendMapBlock(blocks, flags); 228 remoteClient.SendMapBlock(blocks, flags);
212 229
213 // send extra user messages for V3 230 // send extra user messages for V3
214 // because the UI is very confusing 231 // because the UI is very confusing
215 // while we don't fix the hard-coded urls 232 // while we don't fix the hard-coded urls
216 if (flags == 2) 233 if (flags == 2)
217 { 234 {
218 if (regionInfos.Count == 0) 235 if (regionInfos.Count == 0)
219 remoteClient.SendAlertMessage("No regions found with that name."); 236 remoteClient.SendAgentAlertMessage("No regions found with that name.", true);
220 // this seems unnecessary because found regions will show up in the search results 237// else if (regionInfos.Count == 1)
221 //else if (regionInfos.Count == 1) 238// remoteClient.SendAgentAlertMessage("Region found!", false);
222 // remoteClient.SendAlertMessage("Region found!"); 239 }
223 } 240 });
224 } 241 }
225 242
226 private void AddFinalBlock(List<MapBlockData> blocks) 243 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 db1187e..f34cfe5 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -68,26 +68,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
68 private static readonly UUID STOP_UUID = UUID.Random(); 68 private static readonly UUID STOP_UUID = UUID.Random();
69 private static readonly string m_mapLayerPath = "0001/"; 69 private static readonly string m_mapLayerPath = "0001/";
70 70
71 private ManualResetEvent queueEvent = new ManualResetEvent(false);
72 private Queue<MapRequestState> requests = new Queue<MapRequestState>();
73
74 private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false);
75 private Dictionary<UUID, Queue<MapBlockRequestData>> m_mapBlockRequests = new Dictionary<UUID, Queue<MapBlockRequestData>>();
76
71 private IMapImageGenerator m_mapImageGenerator; 77 private IMapImageGenerator m_mapImageGenerator;
72 private IMapImageUploadModule m_mapImageServiceModule; 78 private IMapImageUploadModule m_mapImageServiceModule;
73 79
74 private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>();
75
76 protected Scene m_scene; 80 protected Scene m_scene;
77 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 81 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
78 private int cachedTime = 0; 82 private int cachedTime = 0;
79 private int blacklistTimeout = 10*60*1000; // 10 minutes 83 private int blacklistTimeout = 10*60*1000; // 10 minutes
80 private byte[] myMapImageJPEG; 84 private byte[] myMapImageJPEG;
81 protected volatile bool m_Enabled = false; 85 protected volatile bool m_Enabled = false;
82 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>();
83 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>(); 86 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>();
84 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>(); 87 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>();
85 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>(); 88 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>();
86 private List<UUID> m_rootAgents = new List<UUID>(); 89 private List<UUID> m_rootAgents = new List<UUID>();
87 private volatile bool threadrunning = false; 90 private volatile bool threadrunning = false;
88 91
89 private IServiceThrottleModule m_ServiceThrottle;
90
91 //private int CacheRegionsDistance = 256; 92 //private int CacheRegionsDistance = 256;
92 93
93 #region INonSharedRegionModule Members 94 #region INonSharedRegionModule Members
@@ -98,7 +99,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
98 if (Util.GetConfigVarFromSections<string>( 99 if (Util.GetConfigVarFromSections<string>(
99 config, "WorldMapModule", configSections, "WorldMap") == "WorldMap") 100 config, "WorldMapModule", configSections, "WorldMap") == "WorldMap")
100 m_Enabled = true; 101 m_Enabled = true;
101 102
102 blacklistTimeout 103 blacklistTimeout
103 = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000; 104 = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000;
104 } 105 }
@@ -146,8 +147,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
146 if (!m_Enabled) 147 if (!m_Enabled)
147 return; 148 return;
148 149
149 m_ServiceThrottle = scene.RequestModuleInterface<IServiceThrottleModule>();
150
151 m_mapImageGenerator = m_scene.RequestModuleInterface<IMapImageGenerator>(); 150 m_mapImageGenerator = m_scene.RequestModuleInterface<IMapImageGenerator>();
152 m_mapImageServiceModule = m_scene.RequestModuleInterface<IMapImageUploadModule>(); 151 m_mapImageServiceModule = m_scene.RequestModuleInterface<IMapImageUploadModule>();
153 } 152 }
@@ -197,13 +196,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
197 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; 196 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent;
198 m_scene.EventManager.OnRegionUp += OnRegionUp; 197 m_scene.EventManager.OnRegionUp += OnRegionUp;
199 198
200// StartThread(new object()); 199 StartThread(new object());
201 } 200 }
202 201
203 // this has to be called with a lock on m_scene 202 // this has to be called with a lock on m_scene
204 protected virtual void RemoveHandlers() 203 protected virtual void RemoveHandlers()
205 { 204 {
206// StopThread(); 205 StopThread();
207 206
208 m_scene.EventManager.OnRegionUp -= OnRegionUp; 207 m_scene.EventManager.OnRegionUp -= OnRegionUp;
209 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; 208 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent;
@@ -261,54 +260,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
261 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is 260 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
262 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. 261 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
263 262
264 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 263 //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
265 { 264 //{
266 ScenePresence avatarPresence = null; 265 // ScenePresence avatarPresence = null;
267 266
268 m_scene.TryGetScenePresence(agentID, out avatarPresence); 267 // m_scene.TryGetScenePresence(agentID, out avatarPresence);
269 268
270 if (avatarPresence != null) 269 // if (avatarPresence != null)
271 { 270 // {
272 bool lookup = false; 271 // bool lookup = false;
273 272
274 lock (cachedMapBlocks) 273 // lock (cachedMapBlocks)
275 { 274 // {
276 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) 275 // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
277 { 276 // {
278 List<MapBlockData> mapBlocks; 277 // List<MapBlockData> mapBlocks;
279 278
280 mapBlocks = cachedMapBlocks; 279 // mapBlocks = cachedMapBlocks;
281 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 280 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
282 } 281 // }
283 else 282 // else
284 { 283 // {
285 lookup = true; 284 // lookup = true;
286 } 285 // }
287 } 286 // }
288 if (lookup) 287 // if (lookup)
289 { 288 // {
290 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 289 // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
291 290
292 // Get regions that are within 8 regions of here 291 // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
293 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 292 // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
294 (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocX - 8), 293 // (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
295 (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocX + 8), 294 // (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
296 (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocY - 8), 295 // (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
297 (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocY + 8) ); 296 // foreach (GridRegion r in regions)
298 foreach (GridRegion r in regions) 297 // {
299 { 298 // MapBlockData block = new MapBlockData();
300 MapBlockData block = MapBlockFromGridRegion(r, 0); 299 // MapBlockFromGridRegion(block, r, 0);
301 mapBlocks.Add(block); 300 // mapBlocks.Add(block);
302 } 301 // }
303 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 302 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
304 303
305 lock (cachedMapBlocks) 304 // lock (cachedMapBlocks)
306 cachedMapBlocks = mapBlocks; 305 // cachedMapBlocks = mapBlocks;
307 306
308 cachedTime = Util.UnixTimeSinceEpoch(); 307 // cachedTime = Util.UnixTimeSinceEpoch();
309 } 308 // }
310 } 309 // }
311 } 310 //}
312 311
313 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 312 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
314 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 313 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
@@ -335,7 +334,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
335 protected static OSDMapLayer GetOSDMapLayerResponse() 334 protected static OSDMapLayer GetOSDMapLayerResponse()
336 { 335 {
337 OSDMapLayer mapLayer = new OSDMapLayer(); 336 OSDMapLayer mapLayer = new OSDMapLayer();
337// mapLayer.Right = 2048;
338 mapLayer.Right = 5000; 338 mapLayer.Right = 5000;
339// mapLayer.Top = 2048;
339 mapLayer.Top = 5000; 340 mapLayer.Top = 5000;
340 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); 341 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
341 342
@@ -365,6 +366,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
365 { 366 {
366 m_rootAgents.Remove(AgentId); 367 m_rootAgents.Remove(AgentId);
367 } 368 }
369 lock (m_mapBlockRequestEvent)
370 {
371 if (m_mapBlockRequests.ContainsKey(AgentId))
372 m_mapBlockRequests.Remove(AgentId);
373 }
368 } 374 }
369 #endregion 375 #endregion
370 376
@@ -387,6 +393,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
387 ThreadPriority.BelowNormal, 393 ThreadPriority.BelowNormal,
388 true, 394 true,
389 true); 395 true);
396 WorkManager.StartThread(
397 MapBlockSendThread,
398 string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
399 ThreadPriority.BelowNormal,
400 true,
401 true);
390 } 402 }
391 403
392 /// <summary> 404 /// <summary>
@@ -402,7 +414,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
402 st.itemtype=0; 414 st.itemtype=0;
403 st.regionhandle=0; 415 st.regionhandle=0;
404 416
405 requests.Enqueue(st); 417 lock (requests)
418 {
419 queueEvent.Set();
420 requests.Enqueue(st);
421 }
422
423 MapBlockRequestData req = new MapBlockRequestData();
424
425 req.client = null;
426 req.minX = 0;
427 req.maxX = 0;
428 req.minY = 0;
429 req.maxY = 0;
430 req.flags = 0;
431
432 lock (m_mapBlockRequestEvent)
433 {
434 m_mapBlockRequests[UUID.Zero] = new Queue<MapBlockRequestData>();
435 m_mapBlockRequests[UUID.Zero].Enqueue(req);
436 m_mapBlockRequestEvent.Set();
437 }
406 } 438 }
407 439
408 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 440 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
@@ -418,7 +450,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
418 uint xstart = 0; 450 uint xstart = 0;
419 uint ystart = 0; 451 uint ystart = 0;
420 Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out xstart, out ystart); 452 Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out xstart, out ystart);
421 if (itemtype == (int)GridItemType.AgentLocations) 453
454 if (itemtype == (int)GridItemType.AgentLocations) // Service 6 right now (MAP_ITEM_AGENTS_LOCATION; green dots)
422 { 455 {
423 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) 456 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle)
424 { 457 {
@@ -492,7 +525,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
492 Vector3 max = parcel.AABBMax; 525 Vector3 max = parcel.AABBMax;
493 float x = (min.X+max.X)/2; 526 float x = (min.X+max.X)/2;
494 float y = (min.Y+max.Y)/2; 527 float y = (min.Y+max.Y)/2;
495
496 mapitem = new mapItemReply( 528 mapitem = new mapItemReply(
497 xstart + (uint)x, 529 xstart + (uint)x,
498 ystart + (uint)y, 530 ystart + (uint)y,
@@ -552,12 +584,26 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
552 /// </summary> 584 /// </summary>
553 public void process() 585 public void process()
554 { 586 {
555 //const int MAX_ASYNC_REQUESTS = 20; 587 const int MAX_ASYNC_REQUESTS = 20;
556 try 588 try
557 { 589 {
558 while (true) 590 while (true)
559 { 591 {
560 MapRequestState st = requests.Dequeue(1000); 592 MapRequestState st = new MapRequestState();
593 bool valid = false;
594 queueEvent.WaitOne();
595 lock (requests)
596 {
597 if (requests.Count > 0)
598 {
599 st = requests.Dequeue();
600 valid = true;
601 }
602 if (requests.Count == 0)
603 queueEvent.Reset();
604 }
605 if (!valid)
606 continue;
561 607
562 // end gracefully 608 // end gracefully
563 if (st.agentID == STOP_UUID) 609 if (st.agentID == STOP_UUID)
@@ -575,13 +621,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
575 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) 621 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
576 { 622 {
577 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break 623 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
578 Thread.Sleep(80); 624 Thread.Sleep(100);
579 625
580 RequestMapItemsDelegate d = RequestMapItemsAsync;
581 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
582 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
583 //RequestMapItemsCompleted(response);
584 Interlocked.Increment(ref nAsyncRequests); 626 Interlocked.Increment(ref nAsyncRequests);
627 Util.FireAndForget(x =>
628 {
629 RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
630 });
585 } 631 }
586 } 632 }
587 633
@@ -597,132 +643,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
597 Watchdog.RemoveThread(); 643 Watchdog.RemoveThread();
598 } 644 }
599 645
600 const int MAX_ASYNC_REQUESTS = 20;
601
602 /// <summary> 646 /// <summary>
603 /// Enqueues the map item request into the services throttle processing thread 647 /// Enqueues the map item request into the processing thread
604 /// </summary> 648 /// </summary>
605 /// <param name="state"></param> 649 /// <param name="state"></param>
606 public void EnqueueMapItemRequest(MapRequestState st) 650 public void EnqueueMapItemRequest(MapRequestState state)
607 {
608
609 m_ServiceThrottle.Enqueue("map-item", st.regionhandle.ToString() + st.agentID.ToString(), delegate
610 {
611 if (st.agentID != UUID.Zero)
612 {
613 bool dorequest = true;
614 lock (m_rootAgents)
615 {
616 if (!m_rootAgents.Contains(st.agentID))
617 dorequest = false;
618 }
619
620 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
621 {
622 if (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
623 {
624 // AH!!! Recursive !
625 // Put this request back in the queue and return
626 EnqueueMapItemRequest(st);
627 return;
628 }
629
630 RequestMapItemsDelegate d = RequestMapItemsAsync;
631 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
632 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
633 //RequestMapItemsCompleted(response);
634 Interlocked.Increment(ref nAsyncRequests);
635 }
636 }
637 });
638 }
639
640 /// <summary>
641 /// Sends the mapitem response to the IClientAPI
642 /// </summary>
643 /// <param name="response">The OSDMap Response for the mapitem</param>
644 private void RequestMapItemsCompleted(IAsyncResult iar)
645 { 651 {
646 AsyncResult result = (AsyncResult)iar; 652 lock (requests)
647 RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
648
649 OSDMap response = (OSDMap)icon.EndInvoke(iar);
650
651 Interlocked.Decrement(ref nAsyncRequests);
652
653 if (!response.ContainsKey("requestID"))
654 return;
655
656 UUID requestID = response["requestID"].AsUUID();
657
658 if (requestID != UUID.Zero)
659 { 653 {
660 MapRequestState mrs = new MapRequestState(); 654 queueEvent.Set();
661 mrs.agentID = UUID.Zero; 655 requests.Enqueue(state);
662 lock (m_openRequests)
663 {
664 if (m_openRequests.ContainsKey(requestID))
665 {
666 mrs = m_openRequests[requestID];
667 m_openRequests.Remove(requestID);
668 }
669 }
670 656
671 if (mrs.agentID != UUID.Zero)
672 {
673 ScenePresence av = null;
674 m_scene.TryGetScenePresence(mrs.agentID, out av);
675 if (av != null)
676 {
677 if (response.ContainsKey(mrs.itemtype.ToString()))
678 {
679 List<mapItemReply> returnitems = new List<mapItemReply>();
680 OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()];
681 for (int i = 0; i < itemarray.Count; i++)
682 {
683 OSDMap mapitem = (OSDMap)itemarray[i];
684 mapItemReply mi = new mapItemReply();
685 mi.FromOSD(mapitem);
686 returnitems.Add(mi);
687 }
688 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
689 }
690
691 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
692 uint itemtype = (uint)GridItemType.LandForSale;
693
694 if (response.ContainsKey(itemtype.ToString()))
695 {
696 List<mapItemReply> returnitems = new List<mapItemReply>();
697 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
698 for (int i = 0; i < itemarray.Count; i++)
699 {
700 OSDMap mapitem = (OSDMap)itemarray[i];
701 mapItemReply mi = new mapItemReply();
702 mi.FromOSD(mapitem);
703 returnitems.Add(mi);
704 }
705 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
706 }
707
708 // Service 1 (MAP_ITEM_TELEHUB)
709 itemtype = (uint)GridItemType.Telehub;
710
711 if (response.ContainsKey(itemtype.ToString()))
712 {
713 List<mapItemReply> returnitems = new List<mapItemReply>();
714 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
715 for (int i = 0; i < itemarray.Count; i++)
716 {
717 OSDMap mapitem = (OSDMap)itemarray[i];
718 mapItemReply mi = new mapItemReply();
719 mi.FromOSD(mapitem);
720 returnitems.Add(mi);
721 }
722 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
723 }
724 }
725 }
726 } 657 }
727 } 658 }
728 659
@@ -749,8 +680,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
749 EnqueueMapItemRequest(st); 680 EnqueueMapItemRequest(st);
750 } 681 }
751 682
752 private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
753 uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
754 /// <summary> 683 /// <summary>
755 /// Does the actual remote mapitem request 684 /// Does the actual remote mapitem request
756 /// This should be called from an asynchronous thread 685 /// This should be called from an asynchronous thread
@@ -765,7 +694,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
765 /// <param name="itemtype">passed in from packet</param> 694 /// <param name="itemtype">passed in from packet</param>
766 /// <param name="regionhandle">Region we're looking up</param> 695 /// <param name="regionhandle">Region we're looking up</param>
767 /// <returns></returns> 696 /// <returns></returns>
768 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 697 private void RequestMapItemsAsync(UUID id, uint flags,
769 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 698 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
770 { 699 {
771// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); 700// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
@@ -788,7 +717,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
788 } 717 }
789 718
790 if (blacklisted) 719 if (blacklisted)
791 return new OSDMap(); 720 {
721 Interlocked.Decrement(ref nAsyncRequests);
722 return;
723 }
792 724
793 UUID requestID = UUID.Random(); 725 UUID requestID = UUID.Random();
794 lock (m_cachedRegionMapItemsAddress) 726 lock (m_cachedRegionMapItemsAddress)
@@ -796,6 +728,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
796 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) 728 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
797 httpserver = m_cachedRegionMapItemsAddress[regionhandle]; 729 httpserver = m_cachedRegionMapItemsAddress[regionhandle];
798 } 730 }
731
799 if (httpserver.Length == 0) 732 if (httpserver.Length == 0)
800 { 733 {
801 uint x = 0, y = 0; 734 uint x = 0, y = 0;
@@ -840,18 +773,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
840 773
841 // Can't find the http server 774 // Can't find the http server
842 if (httpserver.Length == 0 || blacklisted) 775 if (httpserver.Length == 0 || blacklisted)
843 return new OSDMap(); 776 {
844 777 Interlocked.Decrement(ref nAsyncRequests);
845 MapRequestState mrs = new MapRequestState(); 778 return;
846 mrs.agentID = id; 779 }
847 mrs.EstateID = EstateID;
848 mrs.flags = flags;
849 mrs.godlike = godlike;
850 mrs.itemtype=itemtype;
851 mrs.regionhandle = regionhandle;
852
853 lock (m_openRequests)
854 m_openRequests.Add(requestID, mrs);
855 780
856 WebRequest mapitemsrequest = null; 781 WebRequest mapitemsrequest = null;
857 try 782 try
@@ -861,7 +786,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
861 catch (Exception e) 786 catch (Exception e)
862 { 787 {
863 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); 788 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e);
864 return new OSDMap(); 789 Interlocked.Decrement(ref nAsyncRequests);
790 return;
865 } 791 }
866 792
867 mapitemsrequest.Method = "POST"; 793 mapitemsrequest.Method = "POST";
@@ -895,13 +821,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
895 821
896 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 822 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
897 823
898 return responseMap; 824 Interlocked.Decrement(ref nAsyncRequests);
825 return;
899 } 826 }
900 catch 827 catch
901 { 828 {
902 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 829 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
903 responseMap["connect"] = OSD.FromBoolean(false); 830 Interlocked.Decrement(ref nAsyncRequests);
904 return responseMap; 831 return;
905 } 832 }
906 finally 833 finally
907 { 834 {
@@ -910,26 +837,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
910 } 837 }
911 838
912 string response_mapItems_reply = null; 839 string response_mapItems_reply = null;
913 { 840 { // get the response
841 StreamReader sr = null;
914 try 842 try
915 { 843 {
916 using (WebResponse webResponse = mapitemsrequest.GetResponse()) 844 WebResponse webResponse = mapitemsrequest.GetResponse();
845 if (webResponse != null)
917 { 846 {
918 if (webResponse != null) 847 sr = new StreamReader(webResponse.GetResponseStream());
919 { 848 response_mapItems_reply = sr.ReadToEnd().Trim();
920 using (Stream s = webResponse.GetResponseStream()) 849 }
921 using (StreamReader sr = new StreamReader(s)) 850 else
922 response_mapItems_reply = sr.ReadToEnd().Trim(); 851 {
923 } 852 Interlocked.Decrement(ref nAsyncRequests);
924 else 853 return;
925 { 854 }
926 return new OSDMap();
927 }
928 }
929 } 855 }
930 catch (WebException) 856 catch (WebException)
931 { 857 {
932 responseMap["connect"] = OSD.FromBoolean(false);
933 lock (m_blacklistedurls) 858 lock (m_blacklistedurls)
934 { 859 {
935 if (!m_blacklistedurls.ContainsKey(httpserver)) 860 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -938,19 +863,25 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
938 863
939 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 864 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
940 865
941 return responseMap; 866 Interlocked.Decrement(ref nAsyncRequests);
867 return;
942 } 868 }
943 catch 869 catch
944 { 870 {
945 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 871 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
946 responseMap["connect"] = OSD.FromBoolean(false);
947 lock (m_blacklistedregions) 872 lock (m_blacklistedregions)
948 { 873 {
949 if (!m_blacklistedregions.ContainsKey(regionhandle)) 874 if (!m_blacklistedregions.ContainsKey(regionhandle))
950 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 875 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
951 } 876 }
952 877
953 return responseMap; 878 Interlocked.Decrement(ref nAsyncRequests);
879 return;
880 }
881 finally
882 {
883 if (sr != null)
884 sr.Close();
954 } 885 }
955 886
956 OSD rezResponse = null; 887 OSD rezResponse = null;
@@ -964,15 +895,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
964 catch (Exception ex) 895 catch (Exception ex)
965 { 896 {
966 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); 897 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message);
967 responseMap["connect"] = OSD.FromBoolean(false);
968
969 lock (m_blacklistedregions) 898 lock (m_blacklistedregions)
970 { 899 {
971 if (!m_blacklistedregions.ContainsKey(regionhandle)) 900 if (!m_blacklistedregions.ContainsKey(regionhandle))
972 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 901 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
973 } 902 }
974 903
975 return responseMap; 904 Interlocked.Decrement(ref nAsyncRequests);
905 return;
976 } 906 }
977 } 907 }
978 908
@@ -986,7 +916,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
986 } 916 }
987 } 917 }
988 918
989 return responseMap; 919 Interlocked.Decrement(ref nAsyncRequests);
920
921 if (id != UUID.Zero)
922 {
923 ScenePresence av = null;
924 m_scene.TryGetScenePresence(id, out av);
925 if (av != null)
926 {
927 if (responseMap.ContainsKey(itemtype.ToString()))
928 {
929 List<mapItemReply> returnitems = new List<mapItemReply>();
930 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
931 for (int i = 0; i < itemarray.Count; i++)
932 {
933 OSDMap mapitem = (OSDMap)itemarray[i];
934 mapItemReply mi = new mapItemReply();
935 mi.x = (uint)mapitem["X"].AsInteger();
936 mi.y = (uint)mapitem["Y"].AsInteger();
937 mi.id = mapitem["ID"].AsUUID();
938 mi.Extra = mapitem["Extra"].AsInteger();
939 mi.Extra2 = mapitem["Extra2"].AsInteger();
940 mi.name = mapitem["Name"].AsString();
941 returnitems.Add(mi);
942 }
943 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
944 }
945
946 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
947 itemtype = 7;
948
949 if (responseMap.ContainsKey(itemtype.ToString()))
950 {
951 List<mapItemReply> returnitems = new List<mapItemReply>();
952 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
953 for (int i = 0; i < itemarray.Count; i++)
954 {
955 OSDMap mapitem = (OSDMap)itemarray[i];
956 mapItemReply mi = new mapItemReply();
957 mi.x = (uint)mapitem["X"].AsInteger();
958 mi.y = (uint)mapitem["Y"].AsInteger();
959 mi.id = mapitem["ID"].AsUUID();
960 mi.Extra = mapitem["Extra"].AsInteger();
961 mi.Extra2 = mapitem["Extra2"].AsInteger();
962 mi.name = mapitem["Name"].AsString();
963 returnitems.Add(mi);
964 }
965 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
966 }
967
968 // Service 1 (MAP_ITEM_TELEHUB)
969 itemtype = 1;
970
971 if (responseMap.ContainsKey(itemtype.ToString()))
972 {
973 List<mapItemReply> returnitems = new List<mapItemReply>();
974 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
975 for (int i = 0; i < itemarray.Count; i++)
976 {
977 OSDMap mapitem = (OSDMap)itemarray[i];
978 mapItemReply mi = new mapItemReply();
979 mi.x = (uint)mapitem["X"].AsInteger();
980 mi.y = (uint)mapitem["Y"].AsInteger();
981 mi.id = mapitem["ID"].AsUUID();
982 mi.Extra = mapitem["Extra"].AsInteger();
983 mi.Extra2 = mapitem["Extra2"].AsInteger();
984 mi.name = mapitem["Name"].AsString();
985 returnitems.Add(mi);
986 }
987 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
988 }
989 }
990 }
990 } 991 }
991 992
992 /// <summary> 993 /// <summary>
@@ -996,8 +997,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
996 /// <param name="minY"></param> 997 /// <param name="minY"></param>
997 /// <param name="maxX"></param> 998 /// <param name="maxX"></param>
998 /// <param name="maxY"></param> 999 /// <param name="maxY"></param>
999 public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 1000 public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1000 { 1001 {
1002 m_log.DebugFormat("[WoldMapModule] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
1003/* this flag does not seem to mean what his says
1001 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible 1004 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible
1002 { 1005 {
1003 List<MapBlockData> response = new List<MapBlockData>(); 1006 List<MapBlockData> response = new List<MapBlockData>();
@@ -1006,24 +1009,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1006 // on an unloaded square. 1009 // on an unloaded square.
1007 // But make sure: Look whether the one we requested is in there 1010 // But make sure: Look whether the one we requested is in there
1008 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1011 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1009 (int)Util.RegionToWorldLoc((uint)minX), (int)Util.RegionToWorldLoc((uint)maxX), 1012 (int)Util.RegionToWorldLoc((uint)minX),
1010 (int)Util.RegionToWorldLoc((uint)minY), (int)Util.RegionToWorldLoc((uint)maxY) ); 1013 (int)Util.RegionToWorldLoc((uint)maxX),
1011 1014 (int)Util.RegionToWorldLoc((uint)minY),
1012 m_log.DebugFormat("[WORLD MAP MODULE] RequestMapBlocks min=<{0},{1}>, max=<{2},{3}>, flag={4}, cntFound={5}", 1015 (int)Util.RegionToWorldLoc((uint)maxY) );
1013 minX, minY, maxX, maxY, flag.ToString("X"), regions.Count); 1016
1014 if (regions != null) 1017 if (regions != null)
1015 { 1018 {
1016 foreach (GridRegion r in regions) 1019 foreach (GridRegion r in regions)
1017 { 1020 {
1018 if (r.RegionLocX == Util.RegionToWorldLoc((uint)minX) 1021 if (r.RegionLocX == Util.RegionToWorldLoc((uint)minX) &&
1019 && r.RegionLocY == Util.RegionToWorldLoc((uint)minY) ) 1022 r.RegionLocY == Util.RegionToWorldLoc((uint)minY))
1020 { 1023 {
1021 // found it => add it to response 1024 // found it => add it to response
1022 // Version 2 viewers can handle the larger regions 1025 MapBlockData block = new MapBlockData();
1023 if ((flag & 2) == 2) 1026 if ((flag & 2) == 2)
1024 response.AddRange(Map2BlockFromGridRegion(r, flag)); 1027 response.AddRange(Map2BlockFromGridRegion(r, flag));
1025 else 1028 else
1026 response.Add(MapBlockFromGridRegion(r, flag)); 1029 {
1030 MapBlockFromGridRegion(block, r, flag);
1031 response.Add(block);
1032 }
1027 break; 1033 break;
1028 } 1034 }
1029 } 1035 }
@@ -1036,7 +1042,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1036 block.X = (ushort)minX; 1042 block.X = (ushort)minX;
1037 block.Y = (ushort)minY; 1043 block.Y = (ushort)minY;
1038 block.Access = (byte)SimAccess.Down; // means 'simulator is offline' 1044 block.Access = (byte)SimAccess.Down; // means 'simulator is offline'
1045<<<<<<< HEAD
1039 // block.Access = (byte)SimAccess.NonExistent; 1046 // block.Access = (byte)SimAccess.NonExistent;
1047=======
1048>>>>>>> avn/ubitvar
1040 response.Add(block); 1049 response.Add(block);
1041 } 1050 }
1042 // The lower 16 bits are an unsigned int16 1051 // The lower 16 bits are an unsigned int16
@@ -1045,36 +1054,126 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1045 else 1054 else
1046 { 1055 {
1047 // normal mapblock request. Use the provided values 1056 // normal mapblock request. Use the provided values
1057 */
1048 GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); 1058 GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag);
1049 } 1059 // }
1050 } 1060 }
1051 1061
1052 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 1062 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1053 { 1063 {
1064 MapBlockRequestData req = new MapBlockRequestData();
1065
1066 req.client = remoteClient;
1067 req.minX = minX;
1068 req.maxX = maxX;
1069 req.minY = minY;
1070 req.maxY = maxY;
1071 req.flags = flag;
1072
1073 lock (m_mapBlockRequestEvent)
1074 {
1075 if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId))
1076 m_mapBlockRequests[remoteClient.AgentId] = new Queue<MapBlockRequestData>();
1077 m_mapBlockRequests[remoteClient.AgentId].Enqueue(req);
1078 m_mapBlockRequestEvent.Set();
1079 }
1080
1081 return new List<MapBlockData>();
1082 }
1083
1084 protected void MapBlockSendThread()
1085 {
1086 while (true)
1087 {
1088 List<MapBlockRequestData> thisRunData = new List<MapBlockRequestData>();
1089
1090 m_mapBlockRequestEvent.WaitOne();
1091 lock (m_mapBlockRequestEvent)
1092 {
1093 int total = 0;
1094 foreach (Queue<MapBlockRequestData> q in m_mapBlockRequests.Values)
1095 {
1096 if (q.Count > 0)
1097 thisRunData.Add(q.Dequeue());
1098
1099 total += q.Count;
1100 }
1101
1102 if (total == 0)
1103 m_mapBlockRequestEvent.Reset();
1104 }
1105
1106 foreach (MapBlockRequestData req in thisRunData)
1107 {
1108 // Null client stops thread
1109 if (req.client == null)
1110 return;
1111
1112 GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags);
1113 }
1114
1115 Thread.Sleep(50);
1116 }
1117 }
1118
1119 protected virtual List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1120 {
1121 List<MapBlockData> allBlocks = new List<MapBlockData>();
1054 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1122 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1055 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1123 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1056 (int)Util.RegionToWorldLoc((uint)(minX - 4)), (int)Util.RegionToWorldLoc((uint)(maxX + 4)), 1124 minX * (int)Constants.RegionSize,
1057 (int)Util.RegionToWorldLoc((uint)(minY - 4)), (int)Util.RegionToWorldLoc((uint)(maxY + 4)) ); 1125 maxX * (int)Constants.RegionSize,
1058 //m_log.DebugFormat("{0} GetAndSendBlocks. min=<{1},{2}>, max=<{3},{4}>, cntFound={5}", 1126 minY * (int)Constants.RegionSize,
1059 // LogHeader, minX, minY, maxX, maxY, regions.Count); 1127 maxY * (int)Constants.RegionSize);
1128// (minX - 4) * (int)Constants.RegionSize,
1129// (maxX + 4) * (int)Constants.RegionSize,
1130// (minY - 4) * (int)Constants.RegionSize,
1131// (maxY + 4) * (int)Constants.RegionSize);
1132
1133 //mb it means this
1134 if(regions.Count == 0 && (flag & 0x10000) != 0)
1135 {
1136 MapBlockData block = new MapBlockData();
1137 block.X = (ushort)minX;
1138 block.Y = (ushort)minY;
1139 block.MapImageId = UUID.Zero;
1140 block.Access = (byte)SimAccess.NonExistent;
1141 allBlocks.Add(block);
1142 mapBlocks.Add(block);
1143 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1144 return allBlocks;
1145 }
1146
1060 foreach (GridRegion r in regions) 1147 foreach (GridRegion r in regions)
1061 { 1148 {
1062 // Version 2 viewers can handle the larger regions 1149 MapBlockData block = new MapBlockData();
1063 if ((flag & 2) == 2) 1150 if ((flag & 2) == 2)
1064 mapBlocks.AddRange(Map2BlockFromGridRegion(r, flag)); 1151 {
1152 List<MapBlockData> blocks = Map2BlockFromGridRegion(r, flag);
1153 mapBlocks.AddRange(blocks);
1154 allBlocks.AddRange(blocks);
1155 }
1065 else 1156 else
1066 mapBlocks.Add(MapBlockFromGridRegion(r, flag)); 1157 {
1158 MapBlockFromGridRegion(block, r, flag);
1159 mapBlocks.Add(block);
1160 allBlocks.Add(block);
1161 }
1162 if (mapBlocks.Count >= 10)
1163 {
1164 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1165 mapBlocks.Clear();
1166 Thread.Sleep(50);
1167 }
1067 } 1168 }
1068 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); 1169 if (mapBlocks.Count > 0)
1170 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1069 1171
1070 return mapBlocks; 1172 return allBlocks;
1071 } 1173 }
1072 1174
1073 // Fill a passed MapBlockData from a GridRegion 1175 public void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag)
1074 public MapBlockData MapBlockFromGridRegion(GridRegion r, uint flag)
1075 { 1176 {
1076 MapBlockData block = new MapBlockData();
1077
1078 block.Access = r.Access; 1177 block.Access = r.Access;
1079 switch (flag & 0xffff) 1178 switch (flag & 0xffff)
1080 { 1179 {
@@ -1089,12 +1188,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1089 break; 1188 break;
1090 } 1189 }
1091 block.Name = r.RegionName; 1190 block.Name = r.RegionName;
1092 block.X = (ushort)Util.WorldToRegionLoc((uint)r.RegionLocX); 1191 block.X = (ushort)(r.RegionLocX / Constants.RegionSize);
1093 block.Y = (ushort)Util.WorldToRegionLoc((uint)r.RegionLocY); 1192 block.Y = (ushort)(r.RegionLocY / Constants.RegionSize);
1094 block.SizeX = (ushort) r.RegionSizeX; 1193 block.SizeX = (ushort)r.RegionSizeX;
1095 block.SizeY = (ushort) r.RegionSizeY; 1194 block.SizeY = (ushort)r.RegionSizeY;
1096
1097 return block;
1098 } 1195 }
1099 1196
1100 public List<MapBlockData> Map2BlockFromGridRegion(GridRegion r, uint flag) 1197 public List<MapBlockData> Map2BlockFromGridRegion(GridRegion r, uint flag)
@@ -1132,7 +1229,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1132 return blocks; 1229 return blocks;
1133 } 1230 }
1134 1231
1135
1136 public Hashtable OnHTTPThrottled(Hashtable keysvals) 1232 public Hashtable OnHTTPThrottled(Hashtable keysvals)
1137 { 1233 {
1138 Hashtable reply = new Hashtable(); 1234 Hashtable reply = new Hashtable();
@@ -1267,7 +1363,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1267 1363
1268 foreach (GridRegion r in regions) 1364 foreach (GridRegion r in regions)
1269 { 1365 {
1270 MapBlockData mapBlock = MapBlockFromGridRegion(r, 0); 1366 MapBlockData mapBlock = new MapBlockData();
1367 MapBlockFromGridRegion(mapBlock, r , 0);
1271 AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); 1368 AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString());
1272 1369
1273 if (texAsset != null) 1370 if (texAsset != null)
@@ -1320,6 +1417,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1320 if (consoleScene != null && consoleScene != m_scene) 1417 if (consoleScene != null && consoleScene != m_scene)
1321 return; 1418 return;
1322 1419
1420 GenerateMaptile();
1421 }
1422/*
1323 if (m_mapImageGenerator == null) 1423 if (m_mapImageGenerator == null)
1324 { 1424 {
1325 Console.WriteLine("No map image generator available for {0}", m_scene.Name); 1425 Console.WriteLine("No map image generator available for {0}", m_scene.Name);
@@ -1329,18 +1429,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1329 using (Bitmap mapbmp = m_mapImageGenerator.CreateMapTile()) 1429 using (Bitmap mapbmp = m_mapImageGenerator.CreateMapTile())
1330 { 1430 {
1331 GenerateMaptile(mapbmp); 1431 GenerateMaptile(mapbmp);
1332 m_mapImageServiceModule.UploadMapTile(m_scene, mapbmp); 1432 if(m_mapImageServiceModule != null)
1433 m_mapImageServiceModule.UploadMapTile(m_scene, mapbmp);
1333 } 1434 }
1334 } 1435 }
1335 1436*/
1336 public OSD HandleRemoteMapItemRequest(string path, OSD request, string endpoint) 1437 public OSD HandleRemoteMapItemRequest(string path, OSD request, string endpoint)
1337 { 1438 {
1338 uint xstart = 0; 1439 uint xstart = 0;
1339 uint ystart = 0; 1440 uint ystart = 0;
1340 1441
1341 Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); 1442 Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out xstart, out ystart);
1342 // m_log.DebugFormat("{0} HandleRemoteMapItemRequest. loc=<{1},{2}>",
1343 // LogHeader, Util.WorldToRegionLoc(xstart), Util.WorldToRegionLoc(ystart));
1344 1443
1345 // Service 6 (MAP_ITEM_AGENTS_LOCATION; green dots) 1444 // Service 6 (MAP_ITEM_AGENTS_LOCATION; green dots)
1346 1445
@@ -1362,7 +1461,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1362 } 1461 }
1363 else 1462 else
1364 { 1463 {
1365 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); 1464 OSDArray responsearr = new OSDArray(); // Don't preallocate. MT (m_scene.GetRootAgentCount());
1366 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 1465 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1367 { 1466 {
1368 OSDMap responsemapdata = new OSDMap(); 1467 OSDMap responsemapdata = new OSDMap();
@@ -1459,15 +1558,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1459 if (m_scene.Heightmap == null) 1558 if (m_scene.Heightmap == null)
1460 return; 1559 return;
1461 1560
1561 if (m_mapImageGenerator == null)
1562 {
1563 Console.WriteLine("No map image generator available for {0}", m_scene.Name);
1564 return;
1565 }
1462 m_log.DebugFormat("[WORLD MAP]: Generating map image for {0}", m_scene.Name); 1566 m_log.DebugFormat("[WORLD MAP]: Generating map image for {0}", m_scene.Name);
1463 1567
1464 using (Bitmap mapbmp = m_mapImageGenerator.CreateMapTile()) 1568 using (Bitmap mapbmp = m_mapImageGenerator.CreateMapTile())
1465 { 1569 {
1466 // V1 (This Module) 1570 // V1 (This Module)
1467 GenerateMaptile(mapbmp); 1571 if(m_scene.RegionInfo.RegionSizeX <= Constants.RegionSize &&
1572 m_scene.RegionInfo.RegionSizeY <= Constants.RegionSize)
1573 GenerateMaptile(mapbmp);
1468 1574
1469 // v2/3 (MapImageServiceModule) 1575 // v2/3 (MapImageServiceModule)
1470 m_mapImageServiceModule.UploadMapTile(m_scene, mapbmp); 1576 if(m_mapImageServiceModule !=null)
1577 m_mapImageServiceModule.UploadMapTile(m_scene, mapbmp);
1471 } 1578 }
1472 } 1579 }
1473 1580
@@ -1553,6 +1660,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1553 { 1660 {
1554 m_rootAgents.Remove(avatar.UUID); 1661 m_rootAgents.Remove(avatar.UUID);
1555 } 1662 }
1663
1664 lock (m_mapBlockRequestEvent)
1665 {
1666 if (m_mapBlockRequests.ContainsKey(avatar.UUID))
1667 m_mapBlockRequests.Remove(avatar.UUID);
1668 }
1556 } 1669 }
1557 1670
1558 public void OnRegionUp(GridRegion otherRegion) 1671 public void OnRegionUp(GridRegion otherRegion)
@@ -1630,15 +1743,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1630 1743
1631 using (SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9))) 1744 using (SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)))
1632 { 1745 {
1633 for (int x = 0 ; x < regionLandTilesX ; x++) 1746 for (int x = 0; x < regionLandTilesX ; x++)
1634 { 1747 {
1635 for (int y = 0 ; y < regionLandTilesY ; y++) 1748 for (int y = 0; y < regionLandTilesY ; y++)
1636 { 1749 {
1637 if (saleBitmap[x, y]) 1750 if (saleBitmap[x, y])
1638 g.FillRectangle( 1751 g.FillRectangle(
1639 yellow, x * landTileSize, 1752 yellow,
1640 regionSizeX - landTileSize - (y * landTileSize), 1753 x * landTileSize,
1641 landTileSize, 1754 regionSizeX - landTileSize - (y * landTileSize),
1755 landTileSize,
1642 landTileSize); 1756 landTileSize);
1643 } 1757 }
1644 } 1758 }
@@ -1668,4 +1782,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1668 public uint itemtype; 1782 public uint itemtype;
1669 public ulong regionhandle; 1783 public ulong regionhandle;
1670 } 1784 }
1785
1786 public struct MapBlockRequestData
1787 {
1788 public IClientAPI client;
1789 public int minX;
1790 public int minY;
1791 public int maxX;
1792 public int maxY;
1793 public uint flags;
1794 }
1671} 1795}