diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World')
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 | ||
44 | namespace OpenSim.Region.CoreModules.World.Permissions | 44 | namespace 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; | |||
29 | using System.Linq; | 29 | using System.Linq; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Timers; | 31 | using System.Timers; |
32 | using System.IO; | ||
33 | using System.Diagnostics; | ||
32 | using System.Threading; | 34 | using System.Threading; |
33 | using System.Collections.Generic; | 35 | using System.Collections.Generic; |
34 | using log4net; | 36 | using 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 | } |