diff options
author | Homer Horwitz | 2008-11-08 17:00:42 +0000 |
---|---|---|
committer | Homer Horwitz | 2008-11-08 17:00:42 +0000 |
commit | 718425e7dc4e677cbed2a9757fe41417d1e6985e (patch) | |
tree | 5566be02bffebbbf0700b5b5c1b881bea64c0bab /OpenSim/Region/Environment/Modules/World/Land | |
parent | Small bugfix for RemoveNeighbourRegion (diff) | |
download | opensim-SC-718425e7dc4e677cbed2a9757fe41417d1e6985e.zip opensim-SC-718425e7dc4e677cbed2a9757fe41417d1e6985e.tar.gz opensim-SC-718425e7dc4e677cbed2a9757fe41417d1e6985e.tar.bz2 opensim-SC-718425e7dc4e677cbed2a9757fe41417d1e6985e.tar.xz |
Added necessary locking to LandManagementModule. As it is used by several
threads concurrently, you'll get bad Heisenbugs without correct locking.
This might fix Mantis#2413
Diffstat (limited to 'OpenSim/Region/Environment/Modules/World/Land')
-rw-r--r-- | OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs | 382 |
1 files changed, 239 insertions, 143 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs index a23ec4d..2235be0 100644 --- a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs | |||
@@ -59,11 +59,11 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
59 | private LandChannel landChannel; | 59 | private LandChannel landChannel; |
60 | private Scene m_scene; | 60 | private Scene m_scene; |
61 | 61 | ||
62 | private readonly int[,] landIDList = new int[64, 64]; | 62 | private readonly int[,] m_landIDList = new int[64, 64]; |
63 | private readonly Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>(); | 63 | private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); |
64 | 64 | ||
65 | private bool landPrimCountTainted; | 65 | private bool m_landPrimCountTainted; |
66 | private int lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; | 66 | private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; |
67 | 67 | ||
68 | private bool m_allowedForcefulBans = true; | 68 | private bool m_allowedForcefulBans = true; |
69 | 69 | ||
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
75 | public void Initialise(Scene scene, IConfigSource source) | 75 | public void Initialise(Scene scene, IConfigSource source) |
76 | { | 76 | { |
77 | m_scene = scene; | 77 | m_scene = scene; |
78 | landIDList.Initialize(); | 78 | m_landIDList.Initialize(); |
79 | landChannel = new LandChannel(scene, this); | 79 | landChannel = new LandChannel(scene, this); |
80 | 80 | ||
81 | parcelInfoCache = new Cache(); | 81 | parcelInfoCache = new Cache(); |
@@ -154,13 +154,18 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
154 | AllowedForcefulBans = forceful; | 154 | AllowedForcefulBans = forceful; |
155 | } | 155 | } |
156 | 156 | ||
157 | public void UpdateLandObject(int local_id, LandData newData) | 157 | public void UpdateLandObject(int local_id, LandData data) |
158 | { | 158 | { |
159 | if (landList.ContainsKey(local_id)) | 159 | LandData newData = data.Copy(); |
160 | newData.LocalID = local_id; | ||
161 | |||
162 | lock (m_landList) | ||
160 | { | 163 | { |
161 | newData.LocalID = local_id; | 164 | if (m_landList.ContainsKey(local_id)) |
162 | landList[local_id].landData = newData.Copy(); | 165 | { |
163 | m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landList[local_id]); | 166 | m_landList[local_id].landData = newData; |
167 | m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); | ||
168 | } | ||
164 | } | 169 | } |
165 | } | 170 | } |
166 | 171 | ||
@@ -176,9 +181,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
176 | public void ResetSimLandObjects() | 181 | public void ResetSimLandObjects() |
177 | { | 182 | { |
178 | //Remove all the land objects in the sim and add a blank, full sim land object set to public | 183 | //Remove all the land objects in the sim and add a blank, full sim land object set to public |
179 | landList.Clear(); | 184 | lock (m_landList) |
180 | lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; | 185 | { |
181 | landIDList.Initialize(); | 186 | m_landList.Clear(); |
187 | m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; | ||
188 | m_landIDList.Initialize(); | ||
189 | } | ||
182 | 190 | ||
183 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); | 191 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); |
184 | 192 | ||
@@ -193,7 +201,10 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
193 | 201 | ||
194 | public List<ILandObject> AllParcels() | 202 | public List<ILandObject> AllParcels() |
195 | { | 203 | { |
196 | return new List<ILandObject>(landList.Values); | 204 | lock (m_landList) |
205 | { | ||
206 | return new List<ILandObject>(m_landList.Values); | ||
207 | } | ||
197 | } | 208 | } |
198 | 209 | ||
199 | public List<ILandObject> ParcelsNearPoint(Vector3 position) | 210 | public List<ILandObject> ParcelsNearPoint(Vector3 position) |
@@ -240,9 +251,14 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
240 | { | 251 | { |
241 | if (m_scene.RegionInfo.RegionID == regionID) | 252 | if (m_scene.RegionInfo.RegionID == regionID) |
242 | { | 253 | { |
243 | if (landList[localLandID] != null) | 254 | ILandObject parcelAvatarIsEntering; |
255 | lock (m_landList) | ||
256 | { | ||
257 | parcelAvatarIsEntering = m_landList[localLandID]; | ||
258 | } | ||
259 | |||
260 | if (parcelAvatarIsEntering != null) | ||
244 | { | 261 | { |
245 | ILandObject parcelAvatarIsEntering = landList[localLandID]; | ||
246 | if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) | 262 | if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) |
247 | { | 263 | { |
248 | if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID)) | 264 | if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID)) |
@@ -279,12 +295,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
279 | { | 295 | { |
280 | if (checkBan.isBannedFromLand(avatar.AgentId)) | 296 | if (checkBan.isBannedFromLand(avatar.AgentId)) |
281 | { | 297 | { |
282 | checkBan.sendLandProperties(-30000, false, (int)ParcelResult.Single, avatar); | 298 | checkBan.sendLandProperties((int)ParcelStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar); |
283 | return; //Only send one | 299 | return; //Only send one |
284 | } | 300 | } |
285 | if (checkBan.isRestrictedFromLand(avatar.AgentId)) | 301 | if (checkBan.isRestrictedFromLand(avatar.AgentId)) |
286 | { | 302 | { |
287 | checkBan.sendLandProperties(-40000, false, (int)ParcelResult.Single, avatar); | 303 | checkBan.sendLandProperties((int)ParcelStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar); |
288 | return; //Only send one | 304 | return; //Only send one |
289 | } | 305 | } |
290 | } | 306 | } |
@@ -376,9 +392,15 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
376 | public void handleParcelAccessRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID, | 392 | public void handleParcelAccessRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID, |
377 | int landLocalID, IClientAPI remote_client) | 393 | int landLocalID, IClientAPI remote_client) |
378 | { | 394 | { |
379 | if (landList.ContainsKey(landLocalID)) | 395 | ILandObject land; |
396 | lock (m_landList) | ||
380 | { | 397 | { |
381 | landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client); | 398 | m_landList.TryGetValue(landLocalID, out land); |
399 | } | ||
400 | |||
401 | if (land != null) | ||
402 | { | ||
403 | m_landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client); | ||
382 | } | 404 | } |
383 | } | 405 | } |
384 | 406 | ||
@@ -386,16 +408,22 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
386 | List<ParcelManager.ParcelAccessEntry> entries, | 408 | List<ParcelManager.ParcelAccessEntry> entries, |
387 | IClientAPI remote_client) | 409 | IClientAPI remote_client) |
388 | { | 410 | { |
389 | if (landList.ContainsKey(landLocalID)) | 411 | ILandObject land; |
412 | lock (m_landList) | ||
413 | { | ||
414 | m_landList.TryGetValue(landLocalID, out land); | ||
415 | } | ||
416 | |||
417 | if (land != null) | ||
390 | { | 418 | { |
391 | if (agentID == landList[landLocalID].landData.OwnerID) | 419 | if (agentID == land.landData.OwnerID) |
392 | { | 420 | { |
393 | landList[landLocalID].updateAccessList(flags, entries, remote_client); | 421 | land.updateAccessList(flags, entries, remote_client); |
394 | } | 422 | } |
395 | } | 423 | } |
396 | else | 424 | else |
397 | { | 425 | { |
398 | Console.WriteLine("INVALID LOCAL LAND ID"); | 426 | m_log.WarnFormat("[LAND]: Invalid local land ID {0}", landLocalID); |
399 | } | 427 | } |
400 | } | 428 | } |
401 | 429 | ||
@@ -412,24 +440,31 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
412 | /// Adds a land object to the stored list and adds them to the landIDList to what they own | 440 | /// Adds a land object to the stored list and adds them to the landIDList to what they own |
413 | /// </summary> | 441 | /// </summary> |
414 | /// <param name="new_land">The land object being added</param> | 442 | /// <param name="new_land">The land object being added</param> |
415 | public ILandObject AddLandObject(ILandObject new_land) | 443 | public ILandObject AddLandObject(ILandObject land) |
416 | { | 444 | { |
417 | lastLandLocalID++; | 445 | ILandObject new_land = land.Copy(); |
418 | new_land.landData.LocalID = lastLandLocalID; | ||
419 | landList.Add(lastLandLocalID, new_land.Copy()); | ||
420 | 446 | ||
421 | bool[,] landBitmap = new_land.getLandBitmap(); | 447 | lock (m_landList) |
422 | for (int x = 0; x < 64; x++) | ||
423 | { | 448 | { |
424 | for (int y = 0; y < 64; y++) | 449 | int newLandLocalID = ++m_lastLandLocalID; |
450 | new_land.landData.LocalID = newLandLocalID; | ||
451 | |||
452 | bool[,] landBitmap = new_land.getLandBitmap(); | ||
453 | for (int x = 0; x < 64; x++) | ||
425 | { | 454 | { |
426 | if (landBitmap[x, y]) | 455 | for (int y = 0; y < 64; y++) |
427 | { | 456 | { |
428 | landIDList[x, y] = lastLandLocalID; | 457 | if (landBitmap[x, y]) |
458 | { | ||
459 | m_landIDList[x, y] = newLandLocalID; | ||
460 | } | ||
429 | } | 461 | } |
430 | } | 462 | } |
463 | |||
464 | m_landList.Add(newLandLocalID, new_land); | ||
431 | } | 465 | } |
432 | landList[lastLandLocalID].forceUpdateLandInfo(); | 466 | |
467 | new_land.forceUpdateLandInfo(); | ||
433 | m_scene.EventManager.TriggerLandObjectAdded(new_land); | 468 | m_scene.EventManager.TriggerLandObjectAdded(new_land); |
434 | return new_land; | 469 | return new_land; |
435 | } | 470 | } |
@@ -440,32 +475,40 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
440 | /// <param name="local_id">Land.localID of the peice of land to remove.</param> | 475 | /// <param name="local_id">Land.localID of the peice of land to remove.</param> |
441 | public void removeLandObject(int local_id) | 476 | public void removeLandObject(int local_id) |
442 | { | 477 | { |
443 | for (int x = 0; x < 64; x++) | 478 | lock (m_landList) |
444 | { | 479 | { |
445 | for (int y = 0; y < 64; y++) | 480 | for (int x = 0; x < 64; x++) |
446 | { | 481 | { |
447 | if (landIDList[x, y] == local_id) | 482 | for (int y = 0; y < 64; y++) |
448 | { | 483 | { |
449 | return; | 484 | if (m_landIDList[x, y] == local_id) |
450 | //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); | 485 | { |
486 | m_log.WarnFormat("[LAND]: Not removing land object {0}; still being used at {1}, {2}", | ||
487 | local_id, x, y); | ||
488 | return; | ||
489 | //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); | ||
490 | } | ||
451 | } | 491 | } |
452 | } | 492 | } |
453 | } | ||
454 | 493 | ||
455 | m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.GlobalID); | 494 | m_scene.EventManager.TriggerLandObjectRemoved(m_landList[local_id].landData.GlobalID); |
456 | landList.Remove(local_id); | 495 | m_landList.Remove(local_id); |
496 | } | ||
457 | } | 497 | } |
458 | 498 | ||
459 | private void performFinalLandJoin(ILandObject master, ILandObject slave) | 499 | private void performFinalLandJoin(ILandObject master, ILandObject slave) |
460 | { | 500 | { |
461 | bool[,] landBitmapSlave = slave.getLandBitmap(); | 501 | bool[,] landBitmapSlave = slave.getLandBitmap(); |
462 | for (int x = 0; x < 64; x++) | 502 | lock (m_landList) |
463 | { | 503 | { |
464 | for (int y = 0; y < 64; y++) | 504 | for (int x = 0; x < 64; x++) |
465 | { | 505 | { |
466 | if (landBitmapSlave[x, y]) | 506 | for (int y = 0; y < 64; y++) |
467 | { | 507 | { |
468 | landIDList[x, y] = master.landData.LocalID; | 508 | if (landBitmapSlave[x, y]) |
509 | { | ||
510 | m_landIDList[x, y] = master.landData.LocalID; | ||
511 | } | ||
469 | } | 512 | } |
470 | } | 513 | } |
471 | } | 514 | } |
@@ -476,11 +519,11 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
476 | 519 | ||
477 | public ILandObject GetLandObject(int parcelLocalID) | 520 | public ILandObject GetLandObject(int parcelLocalID) |
478 | { | 521 | { |
479 | lock (landList) | 522 | lock (m_landList) |
480 | { | 523 | { |
481 | if (landList.ContainsKey(parcelLocalID)) | 524 | if (m_landList.ContainsKey(parcelLocalID)) |
482 | { | 525 | { |
483 | return landList[parcelLocalID]; | 526 | return m_landList[parcelLocalID]; |
484 | } | 527 | } |
485 | } | 528 | } |
486 | return null; | 529 | return null; |
@@ -511,7 +554,10 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
511 | { | 554 | { |
512 | return null; | 555 | return null; |
513 | } | 556 | } |
514 | return landList[landIDList[x, y]]; | 557 | lock (m_landList) |
558 | { | ||
559 | return m_landList[m_landIDList[x, y]]; | ||
560 | } | ||
515 | } | 561 | } |
516 | 562 | ||
517 | public ILandObject GetLandObject(int x, int y) | 563 | public ILandObject GetLandObject(int x, int y) |
@@ -522,7 +568,10 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
522 | // they happen every time at border crossings | 568 | // they happen every time at border crossings |
523 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); | 569 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); |
524 | } | 570 | } |
525 | return landList[landIDList[x / 4, y / 4]]; | 571 | lock (m_landIDList) |
572 | { | ||
573 | return m_landList[m_landIDList[x / 4, y / 4]]; | ||
574 | } | ||
526 | } | 575 | } |
527 | 576 | ||
528 | #endregion | 577 | #endregion |
@@ -531,20 +580,23 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
531 | 580 | ||
532 | public void ResetAllLandPrimCounts() | 581 | public void ResetAllLandPrimCounts() |
533 | { | 582 | { |
534 | foreach (LandObject p in landList.Values) | 583 | lock (m_landList) |
535 | { | 584 | { |
536 | p.resetLandPrimCounts(); | 585 | foreach (LandObject p in m_landList.Values) |
586 | { | ||
587 | p.resetLandPrimCounts(); | ||
588 | } | ||
537 | } | 589 | } |
538 | } | 590 | } |
539 | 591 | ||
540 | public void SetPrimsTainted() | 592 | public void SetPrimsTainted() |
541 | { | 593 | { |
542 | landPrimCountTainted = true; | 594 | m_landPrimCountTainted = true; |
543 | } | 595 | } |
544 | 596 | ||
545 | public bool IsLandPrimCountTainted() | 597 | public bool IsLandPrimCountTainted() |
546 | { | 598 | { |
547 | return landPrimCountTainted; | 599 | return m_landPrimCountTainted; |
548 | } | 600 | } |
549 | 601 | ||
550 | public void AddPrimToLandPrimCounts(SceneObjectGroup obj) | 602 | public void AddPrimToLandPrimCounts(SceneObjectGroup obj) |
@@ -559,32 +611,46 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
559 | 611 | ||
560 | public void RemovePrimFromLandPrimCounts(SceneObjectGroup obj) | 612 | public void RemovePrimFromLandPrimCounts(SceneObjectGroup obj) |
561 | { | 613 | { |
562 | foreach (LandObject p in landList.Values) | 614 | |
615 | lock (m_landList) | ||
563 | { | 616 | { |
564 | p.removePrimFromCount(obj); | 617 | foreach (LandObject p in m_landList.Values) |
618 | { | ||
619 | p.removePrimFromCount(obj); | ||
620 | } | ||
565 | } | 621 | } |
566 | } | 622 | } |
567 | 623 | ||
568 | public void FinalizeLandPrimCountUpdate() | 624 | public void FinalizeLandPrimCountUpdate() |
569 | { | 625 | { |
626 | m_log.Debug("Called FinalizeLandPrimCountUpdate start"); | ||
570 | //Get Simwide prim count for owner | 627 | //Get Simwide prim count for owner |
571 | Dictionary<UUID, List<LandObject>> landOwnersAndParcels = new Dictionary<UUID, List<LandObject>>(); | 628 | Dictionary<UUID, List<LandObject>> landOwnersAndParcels = new Dictionary<UUID, List<LandObject>>(); |
572 | foreach (LandObject p in landList.Values) | 629 | lock (m_landList) |
573 | { | 630 | { |
574 | if (!landOwnersAndParcels.ContainsKey(p.landData.OwnerID)) | 631 | m_log.DebugFormat("[LAND]: Got {0} parcels", m_landList.Count); |
632 | foreach (LandObject p in m_landList.Values) | ||
575 | { | 633 | { |
576 | List<LandObject> tempList = new List<LandObject>(); | 634 | m_log.DebugFormat("processing land {0}", p.GetHashCode()); |
577 | tempList.Add(p); | 635 | if (!landOwnersAndParcels.ContainsKey(p.landData.OwnerID)) |
578 | landOwnersAndParcels.Add(p.landData.OwnerID, tempList); | 636 | { |
579 | } | 637 | m_log.DebugFormat("adding new owner {0} to landlist", p.landData.OwnerID); |
580 | else | 638 | List<LandObject> tempList = new List<LandObject>(); |
581 | { | 639 | tempList.Add(p); |
582 | landOwnersAndParcels[p.landData.OwnerID].Add(p); | 640 | landOwnersAndParcels.Add(p.landData.OwnerID, tempList); |
641 | } | ||
642 | else | ||
643 | { | ||
644 | m_log.DebugFormat("adding to owner {0}", p.landData.OwnerID); | ||
645 | landOwnersAndParcels[p.landData.OwnerID].Add(p); | ||
646 | } | ||
583 | } | 647 | } |
584 | } | 648 | } |
585 | 649 | ||
650 | m_log.DebugFormat("got {0} owners of land", landOwnersAndParcels.Count); | ||
586 | foreach (UUID owner in landOwnersAndParcels.Keys) | 651 | foreach (UUID owner in landOwnersAndParcels.Keys) |
587 | { | 652 | { |
653 | m_log.DebugFormat("processing owner {0}", owner); | ||
588 | int simArea = 0; | 654 | int simArea = 0; |
589 | int simPrims = 0; | 655 | int simPrims = 0; |
590 | foreach (LandObject p in landOwnersAndParcels[owner]) | 656 | foreach (LandObject p in landOwnersAndParcels[owner]) |
@@ -592,18 +658,23 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
592 | simArea += p.landData.Area; | 658 | simArea += p.landData.Area; |
593 | simPrims += p.landData.OwnerPrims + p.landData.OtherPrims + p.landData.GroupPrims + | 659 | simPrims += p.landData.OwnerPrims + p.landData.OtherPrims + p.landData.GroupPrims + |
594 | p.landData.SelectedPrims; | 660 | p.landData.SelectedPrims; |
661 | m_log.DebugFormat("added {0} m² of land, total {1}", p.landData.Area, simArea); | ||
595 | } | 662 | } |
596 | 663 | ||
664 | m_log.DebugFormat("setting total area of {0} to {1} for {2} parcels", owner, simArea, landOwnersAndParcels[owner].Count); | ||
597 | foreach (LandObject p in landOwnersAndParcels[owner]) | 665 | foreach (LandObject p in landOwnersAndParcels[owner]) |
598 | { | 666 | { |
667 | m_log.DebugFormat("... in land {0}", p.GetHashCode()); | ||
599 | p.landData.SimwideArea = simArea; | 668 | p.landData.SimwideArea = simArea; |
600 | p.landData.SimwidePrims = simPrims; | 669 | p.landData.SimwidePrims = simPrims; |
601 | } | 670 | } |
602 | } | 671 | } |
672 | m_log.Debug("Called FinalizeLandPrimCountUpdate end"); | ||
603 | } | 673 | } |
604 | 674 | ||
605 | public void UpdateLandPrimCounts() | 675 | public void UpdateLandPrimCounts() |
606 | { | 676 | { |
677 | m_log.Debug("Called UpdateLandPrimCounts"); | ||
607 | ResetAllLandPrimCounts(); | 678 | ResetAllLandPrimCounts(); |
608 | lock (m_scene.Entities) | 679 | lock (m_scene.Entities) |
609 | { | 680 | { |
@@ -619,15 +690,16 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
619 | } | 690 | } |
620 | } | 691 | } |
621 | FinalizeLandPrimCountUpdate(); | 692 | FinalizeLandPrimCountUpdate(); |
622 | landPrimCountTainted = false; | 693 | m_landPrimCountTainted = false; |
623 | } | 694 | } |
624 | 695 | ||
625 | public void PerformParcelPrimCountUpdate() | 696 | public void PerformParcelPrimCountUpdate() |
626 | { | 697 | { |
698 | m_log.Debug("Called PerformParcelPrimCountUpdate"); | ||
627 | ResetAllLandPrimCounts(); | 699 | ResetAllLandPrimCounts(); |
628 | m_scene.EventManager.TriggerParcelPrimCountUpdate(); | 700 | m_scene.EventManager.TriggerParcelPrimCountUpdate(); |
629 | FinalizeLandPrimCountUpdate(); | 701 | FinalizeLandPrimCountUpdate(); |
630 | landPrimCountTainted = false; | 702 | m_landPrimCountTainted = false; |
631 | } | 703 | } |
632 | 704 | ||
633 | /// <summary> | 705 | /// <summary> |
@@ -684,9 +756,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
684 | 756 | ||
685 | //Now, lets set the subdivision area of the original to false | 757 | //Now, lets set the subdivision area of the original to false |
686 | int startLandObjectIndex = startLandObject.landData.LocalID; | 758 | int startLandObjectIndex = startLandObject.landData.LocalID; |
687 | landList[startLandObjectIndex].setLandBitmap( | 759 | lock (m_landList) |
688 | newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); | 760 | { |
689 | landList[startLandObjectIndex].forceUpdateLandInfo(); | 761 | m_landList[startLandObjectIndex].setLandBitmap( |
762 | newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); | ||
763 | m_landList[startLandObjectIndex].forceUpdateLandInfo(); | ||
764 | } | ||
690 | 765 | ||
691 | SetPrimsTainted(); | 766 | SetPrimsTainted(); |
692 | 767 | ||
@@ -746,13 +821,16 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
746 | return; | 821 | return; |
747 | } | 822 | } |
748 | } | 823 | } |
749 | foreach (ILandObject slaveLandObject in selectedLandObjects) | 824 | |
825 | lock (m_landList) | ||
750 | { | 826 | { |
751 | landList[masterLandObject.landData.LocalID].setLandBitmap( | 827 | foreach (ILandObject slaveLandObject in selectedLandObjects) |
752 | slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); | 828 | { |
753 | performFinalLandJoin(masterLandObject, slaveLandObject); | 829 | m_landList[masterLandObject.landData.LocalID].setLandBitmap( |
830 | slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); | ||
831 | performFinalLandJoin(masterLandObject, slaveLandObject); | ||
832 | } | ||
754 | } | 833 | } |
755 | |||
756 | SetPrimsTainted(); | 834 | SetPrimsTainted(); |
757 | 835 | ||
758 | masterLandObject.sendLandUpdateToAvatarsOverMe(); | 836 | masterLandObject.sendLandUpdateToAvatarsOverMe(); |
@@ -892,10 +970,13 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
892 | 970 | ||
893 | public void handleParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) | 971 | public void handleParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) |
894 | { | 972 | { |
895 | if (landList.ContainsKey(localID)) | 973 | ILandObject land; |
974 | lock (m_landList) | ||
896 | { | 975 | { |
897 | landList[localID].updateLandProperties(args, remote_client); | 976 | m_landList.TryGetValue(localID, out land); |
898 | } | 977 | } |
978 | |||
979 | if (land != null) land.updateLandProperties(args, remote_client); | ||
899 | } | 980 | } |
900 | 981 | ||
901 | public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) | 982 | public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) |
@@ -910,67 +991,88 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
910 | 991 | ||
911 | public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) | 992 | public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) |
912 | { | 993 | { |
913 | landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); | 994 | m_landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); |
914 | } | 995 | } |
915 | 996 | ||
916 | public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) | 997 | public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) |
917 | { | 998 | { |
918 | lock (landList) | 999 | ILandObject land; |
1000 | lock (m_landList) | ||
919 | { | 1001 | { |
920 | if (landList.ContainsKey(local_id)) | 1002 | m_landList.TryGetValue(local_id, out land); |
921 | { | 1003 | } |
922 | landList[local_id].sendLandObjectOwners(remote_client); | 1004 | |
923 | } | 1005 | if (land != null) |
924 | else | 1006 | { |
925 | { | 1007 | m_landList[local_id].sendLandObjectOwners(remote_client); |
926 | System.Console.WriteLine("[PARCEL]: Invalid land object passed for parcel object owner request"); | 1008 | } |
927 | } | 1009 | else |
1010 | { | ||
1011 | m_log.WarnFormat("[PARCEL]: Invalid land object {0} passed for parcel object owner request", local_id); | ||
928 | } | 1012 | } |
929 | } | 1013 | } |
930 | 1014 | ||
931 | public void handleParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client) | 1015 | public void handleParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client) |
932 | { | 1016 | { |
933 | if (landList.ContainsKey(local_id)) | 1017 | ILandObject land; |
1018 | lock (m_landList) | ||
1019 | { | ||
1020 | m_landList.TryGetValue(local_id, out land); | ||
1021 | } | ||
1022 | |||
1023 | if (land != null) | ||
934 | { | 1024 | { |
935 | if (m_scene.ExternalChecks.ExternalChecksCanBeGodLike(remote_client.AgentId)) | 1025 | if (m_scene.ExternalChecks.ExternalChecksCanBeGodLike(remote_client.AgentId)) |
936 | { | 1026 | { |
937 | landList[local_id].landData.OwnerID = ownerID; | 1027 | land.landData.OwnerID = ownerID; |
938 | 1028 | ||
939 | m_scene.Broadcast(SendParcelOverlay); | 1029 | m_scene.Broadcast(SendParcelOverlay); |
940 | landList[local_id].sendLandUpdateToClient(remote_client); | 1030 | land.sendLandUpdateToClient(remote_client); |
941 | } | 1031 | } |
942 | } | 1032 | } |
943 | } | 1033 | } |
944 | 1034 | ||
945 | public void handleParcelAbandonRequest(int local_id, IClientAPI remote_client) | 1035 | public void handleParcelAbandonRequest(int local_id, IClientAPI remote_client) |
946 | { | 1036 | { |
947 | if (landList.ContainsKey(local_id)) | 1037 | ILandObject land; |
1038 | lock (m_landList) | ||
948 | { | 1039 | { |
949 | if (m_scene.ExternalChecks.ExternalChecksCanAbandonParcel(remote_client.AgentId, landList[local_id])) | 1040 | m_landList.TryGetValue(local_id, out land); |
1041 | } | ||
1042 | |||
1043 | if (land != null) | ||
1044 | { | ||
1045 | if (m_scene.ExternalChecks.ExternalChecksCanAbandonParcel(remote_client.AgentId, land)) | ||
950 | { | 1046 | { |
951 | if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero) | 1047 | if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero) |
952 | landList[local_id].landData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 1048 | land.landData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
953 | else | 1049 | else |
954 | landList[local_id].landData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; | 1050 | land.landData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; |
955 | m_scene.Broadcast(SendParcelOverlay); | 1051 | m_scene.Broadcast(SendParcelOverlay); |
956 | landList[local_id].sendLandUpdateToClient(remote_client); | 1052 | land.sendLandUpdateToClient(remote_client); |
957 | } | 1053 | } |
958 | } | 1054 | } |
959 | } | 1055 | } |
960 | 1056 | ||
961 | public void handleParcelReclaim(int local_id, IClientAPI remote_client) | 1057 | public void handleParcelReclaim(int local_id, IClientAPI remote_client) |
962 | { | 1058 | { |
963 | if (landList.ContainsKey(local_id)) | 1059 | ILandObject land; |
1060 | lock (m_landList) | ||
1061 | { | ||
1062 | m_landList.TryGetValue(local_id, out land); | ||
1063 | } | ||
1064 | |||
1065 | if (land != null) | ||
964 | { | 1066 | { |
965 | if (m_scene.ExternalChecks.ExternalChecksCanReclaimParcel(remote_client.AgentId, landList[local_id])) | 1067 | if (m_scene.ExternalChecks.ExternalChecksCanReclaimParcel(remote_client.AgentId, land)) |
966 | { | 1068 | { |
967 | if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero) | 1069 | if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero) |
968 | landList[local_id].landData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 1070 | land.landData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
969 | else | 1071 | else |
970 | landList[local_id].landData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; | 1072 | land.landData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; |
971 | landList[local_id].landData.ClaimDate = Util.UnixTimeSinceEpoch(); | 1073 | land.landData.ClaimDate = Util.UnixTimeSinceEpoch(); |
972 | m_scene.Broadcast(SendParcelOverlay); | 1074 | m_scene.Broadcast(SendParcelOverlay); |
973 | landList[local_id].sendLandUpdateToClient(remote_client); | 1075 | land.sendLandUpdateToClient(remote_client); |
974 | } | 1076 | } |
975 | } | 1077 | } |
976 | } | 1078 | } |
@@ -984,13 +1086,15 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
984 | { | 1086 | { |
985 | if (e.economyValidated && e.landValidated) | 1087 | if (e.economyValidated && e.landValidated) |
986 | { | 1088 | { |
987 | lock (landList) | 1089 | ILandObject land; |
1090 | lock (m_landList) | ||
988 | { | 1091 | { |
989 | if (landList.ContainsKey(e.parcelLocalID)) | 1092 | m_landList.TryGetValue(e.parcelLocalID, out land); |
990 | { | 1093 | } |
991 | landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint)e.transactionID, e.parcelPrice, e.parcelArea); | 1094 | |
992 | return; | 1095 | if (land != null) |
993 | } | 1096 | { |
1097 | land.updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint)e.transactionID, e.parcelPrice, e.parcelArea); | ||
994 | } | 1098 | } |
995 | } | 1099 | } |
996 | } | 1100 | } |
@@ -1004,13 +1108,11 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
1004 | if (e.landValidated == false) | 1108 | if (e.landValidated == false) |
1005 | { | 1109 | { |
1006 | ILandObject lob = null; | 1110 | ILandObject lob = null; |
1007 | lock (landList) | 1111 | lock (m_landList) |
1008 | { | 1112 | { |
1009 | if (landList.ContainsKey(e.parcelLocalID)) | 1113 | m_landList.TryGetValue(e.parcelLocalID, out lob); |
1010 | { | ||
1011 | lob = landList[e.parcelLocalID]; | ||
1012 | } | ||
1013 | } | 1114 | } |
1115 | |||
1014 | if (lob != null) | 1116 | if (lob != null) |
1015 | { | 1117 | { |
1016 | UUID AuthorizedID = lob.landData.AuthBuyerID; | 1118 | UUID AuthorizedID = lob.landData.AuthBuyerID; |
@@ -1021,11 +1123,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
1021 | (uint)(Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0); | 1123 | (uint)(Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0); |
1022 | if ((AuthorizedID == UUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale) | 1124 | if ((AuthorizedID == UUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale) |
1023 | { | 1125 | { |
1024 | lock (e) | 1126 | // TODO I don't think we have to lock it here, no? |
1025 | { | 1127 | //lock (e) |
1128 | //{ | ||
1026 | e.parcelOwnerID = pOwnerID; | 1129 | e.parcelOwnerID = pOwnerID; |
1027 | e.landValidated = true; | 1130 | e.landValidated = true; |
1028 | } | 1131 | //} |
1029 | } | 1132 | } |
1030 | } | 1133 | } |
1031 | } | 1134 | } |
@@ -1037,20 +1140,8 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
1037 | { | 1140 | { |
1038 | for (int i = 0; i < data.Count; i++) | 1141 | for (int i = 0; i < data.Count; i++) |
1039 | { | 1142 | { |
1040 | //try | ||
1041 | //{ | ||
1042 | IncomingLandObjectFromStorage(data[i]); | 1143 | IncomingLandObjectFromStorage(data[i]); |
1043 | //} | 1144 | } |
1044 | //catch (Exception ex) | ||
1045 | //{ | ||
1046 | //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString()); | ||
1047 | //throw ex; | ||
1048 | //} | ||
1049 | } | ||
1050 | //foreach (LandData parcel in data) | ||
1051 | //{ | ||
1052 | // IncomingLandObjectFromStorage(parcel); | ||
1053 | //} | ||
1054 | } | 1145 | } |
1055 | 1146 | ||
1056 | public void IncomingLandObjectFromStorage(LandData data) | 1147 | public void IncomingLandObjectFromStorage(LandData data) |
@@ -1064,13 +1155,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
1064 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) | 1155 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) |
1065 | { | 1156 | { |
1066 | ILandObject selectedParcel = null; | 1157 | ILandObject selectedParcel = null; |
1067 | lock (landList) | 1158 | lock (m_landList) |
1068 | { | 1159 | { |
1069 | if (landList.ContainsKey(localID)) | 1160 | m_landList.TryGetValue(localID, out selectedParcel); |
1070 | selectedParcel = landList[localID]; | ||
1071 | } | 1161 | } |
1072 | if (selectedParcel == null) | 1162 | |
1073 | return; | 1163 | if (selectedParcel == null) return; |
1074 | 1164 | ||
1075 | if (returnType == 16) // parcel return | 1165 | if (returnType == 16) // parcel return |
1076 | { | 1166 | { |
@@ -1087,9 +1177,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
1087 | 1177 | ||
1088 | public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) | 1178 | public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) |
1089 | { | 1179 | { |
1090 | foreach (LandObject obj in landList.Values) | 1180 | lock (m_landList) |
1091 | { | 1181 | { |
1092 | obj.setParcelObjectMaxOverride(overrideDel); | 1182 | foreach (LandObject obj in m_landList.Values) |
1183 | { | ||
1184 | obj.setParcelObjectMaxOverride(overrideDel); | ||
1185 | } | ||
1093 | } | 1186 | } |
1094 | } | 1187 | } |
1095 | 1188 | ||
@@ -1234,19 +1327,22 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
1234 | m_log.Debug("[LAND] got no parcelinfo; not sending"); | 1327 | m_log.Debug("[LAND] got no parcelinfo; not sending"); |
1235 | } | 1328 | } |
1236 | 1329 | ||
1237 | public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID,int otherCleanTime) | 1330 | public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime) |
1238 | { | 1331 | { |
1239 | if (!landList.ContainsKey(localID)) | 1332 | ILandObject land; |
1240 | return; | 1333 | lock (m_landList) |
1334 | { | ||
1335 | m_landList.TryGetValue(localID, out land); | ||
1336 | } | ||
1241 | 1337 | ||
1242 | ILandObject landObject = landList[localID]; | 1338 | if(land == null) return; |
1243 | 1339 | ||
1244 | if (!m_scene.ExternalChecks.ExternalChecksCanEditParcel(remoteClient.AgentId, landObject)) | 1340 | if (!m_scene.ExternalChecks.ExternalChecksCanEditParcel(remoteClient.AgentId, land)) |
1245 | return; | 1341 | return; |
1246 | 1342 | ||
1247 | landObject.landData.OtherCleanTime = otherCleanTime; | 1343 | land.landData.OtherCleanTime = otherCleanTime; |
1248 | 1344 | ||
1249 | UpdateLandObject(localID, landObject.landData); | 1345 | UpdateLandObject(localID, land.landData); |
1250 | } | 1346 | } |
1251 | } | 1347 | } |
1252 | } | 1348 | } |