diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 95 |
1 files changed, 76 insertions, 19 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 99db7ff..5c20899 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -66,6 +66,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
66 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 66 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
67 | private static readonly string LogHeader = "[LAND MANAGEMENT MODULE]"; | 67 | private static readonly string LogHeader = "[LAND MANAGEMENT MODULE]"; |
68 | 68 | ||
69 | /// <summary> | ||
70 | /// Minimum land unit size in region co-ordinates. | ||
71 | /// </summary> | ||
72 | public const int LandUnit = 4; | ||
73 | |||
69 | private static readonly string remoteParcelRequestPath = "0009/"; | 74 | private static readonly string remoteParcelRequestPath = "0009/"; |
70 | 75 | ||
71 | private LandChannel landChannel; | 76 | private LandChannel landChannel; |
@@ -79,7 +84,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
79 | /// Local land ids at specified region co-ordinates (region size / 4) | 84 | /// Local land ids at specified region co-ordinates (region size / 4) |
80 | /// </value> | 85 | /// </value> |
81 | private int[,] m_landIDList; | 86 | private int[,] m_landIDList; |
82 | private const int landUnit = 4; | ||
83 | 87 | ||
84 | /// <value> | 88 | /// <value> |
85 | /// Land objects keyed by local id | 89 | /// Land objects keyed by local id |
@@ -112,7 +116,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
112 | public void AddRegion(Scene scene) | 116 | public void AddRegion(Scene scene) |
113 | { | 117 | { |
114 | m_scene = scene; | 118 | m_scene = scene; |
115 | m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; | 119 | m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; |
116 | 120 | ||
117 | m_landIDList.Initialize(); | 121 | m_landIDList.Initialize(); |
118 | landChannel = new LandChannel(scene, this); | 122 | landChannel = new LandChannel(scene, this); |
@@ -296,7 +300,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
296 | { | 300 | { |
297 | m_landList.Clear(); | 301 | m_landList.Clear(); |
298 | m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; | 302 | m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; |
299 | m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; | 303 | m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; |
300 | m_landIDList.Initialize(); | 304 | m_landIDList.Initialize(); |
301 | } | 305 | } |
302 | } | 306 | } |
@@ -590,7 +594,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
590 | /// <summary> | 594 | /// <summary> |
591 | /// Adds a land object to the stored list and adds them to the landIDList to what they own | 595 | /// Adds a land object to the stored list and adds them to the landIDList to what they own |
592 | /// </summary> | 596 | /// </summary> |
593 | /// <param name="new_land">The land object being added</param> | 597 | /// <param name="new_land"> |
598 | /// The land object being added. | ||
599 | /// Will return null if this overlaps with an existing parcel that has not had its bitmap adjusted. | ||
600 | /// </param> | ||
594 | public ILandObject AddLandObject(ILandObject land) | 601 | public ILandObject AddLandObject(ILandObject land) |
595 | { | 602 | { |
596 | ILandObject new_land = land.Copy(); | 603 | ILandObject new_land = land.Copy(); |
@@ -602,7 +609,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
602 | 609 | ||
603 | lock (m_landList) | 610 | lock (m_landList) |
604 | { | 611 | { |
605 | int newLandLocalID = ++m_lastLandLocalID; | 612 | int newLandLocalID = m_lastLandLocalID + 1; |
606 | new_land.LandData.LocalID = newLandLocalID; | 613 | new_land.LandData.LocalID = newLandLocalID; |
607 | 614 | ||
608 | bool[,] landBitmap = new_land.GetLandBitmap(); | 615 | bool[,] landBitmap = new_land.GetLandBitmap(); |
@@ -617,6 +624,33 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
617 | } | 624 | } |
618 | else | 625 | else |
619 | { | 626 | { |
627 | // If other land objects still believe that they occupy any parts of the same space, | ||
628 | // then do not allow the add to proceed. | ||
629 | for (int x = 0; x < landBitmap.GetLength(0); x++) | ||
630 | { | ||
631 | for (int y = 0; y < landBitmap.GetLength(1); y++) | ||
632 | { | ||
633 | if (landBitmap[x, y]) | ||
634 | { | ||
635 | int lastRecordedLandId = m_landIDList[x, y]; | ||
636 | |||
637 | if (lastRecordedLandId > 0) | ||
638 | { | ||
639 | ILandObject lastRecordedLo = m_landList[lastRecordedLandId]; | ||
640 | |||
641 | if (lastRecordedLo.LandBitmap[x, y]) | ||
642 | { | ||
643 | m_log.ErrorFormat( | ||
644 | "{0}: Cannot add parcel \"{1}\", local ID {2} at tile {3},{4} because this is still occupied by parcel \"{5}\", local ID {6}.", | ||
645 | LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y, lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID); | ||
646 | |||
647 | return null; | ||
648 | } | ||
649 | } | ||
650 | } | ||
651 | } | ||
652 | } | ||
653 | |||
620 | for (int x = 0; x < landBitmap.GetLength(0); x++) | 654 | for (int x = 0; x < landBitmap.GetLength(0); x++) |
621 | { | 655 | { |
622 | for (int y = 0; y < landBitmap.GetLength(1); y++) | 656 | for (int y = 0; y < landBitmap.GetLength(1); y++) |
@@ -626,7 +660,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
626 | // m_log.DebugFormat( | 660 | // m_log.DebugFormat( |
627 | // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", | 661 | // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", |
628 | // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName); | 662 | // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName); |
629 | 663 | ||
630 | m_landIDList[x, y] = newLandLocalID; | 664 | m_landIDList[x, y] = newLandLocalID; |
631 | } | 665 | } |
632 | } | 666 | } |
@@ -634,10 +668,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
634 | } | 668 | } |
635 | 669 | ||
636 | m_landList.Add(newLandLocalID, new_land); | 670 | m_landList.Add(newLandLocalID, new_land); |
671 | m_lastLandLocalID++; | ||
637 | } | 672 | } |
638 | 673 | ||
639 | new_land.ForceUpdateLandInfo(); | 674 | new_land.ForceUpdateLandInfo(); |
640 | m_scene.EventManager.TriggerLandObjectAdded(new_land); | 675 | m_scene.EventManager.TriggerLandObjectAdded(new_land); |
676 | |||
641 | return new_land; | 677 | return new_land; |
642 | } | 678 | } |
643 | 679 | ||
@@ -801,8 +837,18 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
801 | return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */); | 837 | return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */); |
802 | } | 838 | } |
803 | 839 | ||
804 | // Given a region position, return the parcel land object for that location | 840 | /// <summary> |
805 | private ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectNotFound) | 841 | /// Given a region position, return the parcel land object for that location |
842 | /// </summary> | ||
843 | /// <returns> | ||
844 | /// The land object. | ||
845 | /// </returns> | ||
846 | /// <param name='x'></param> | ||
847 | /// <param name='y'></param> | ||
848 | /// <param name='returnNullIfLandObjectNotFound'> | ||
849 | /// Return null if the land object requested is not within the region's bounds. | ||
850 | /// </param> | ||
851 | private ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds) | ||
806 | { | 852 | { |
807 | ILandObject ret = null; | 853 | ILandObject ret = null; |
808 | 854 | ||
@@ -810,7 +856,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
810 | { | 856 | { |
811 | // These exceptions here will cause a lot of complaints from the users specifically because | 857 | // These exceptions here will cause a lot of complaints from the users specifically because |
812 | // they happen every time at border crossings | 858 | // they happen every time at border crossings |
813 | if (returnNullIfLandObjectNotFound) | 859 | if (returnNullIfLandObjectOutsideBounds) |
814 | return null; | 860 | return null; |
815 | else | 861 | else |
816 | throw new Exception( | 862 | throw new Exception( |
@@ -823,7 +869,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
823 | { | 869 | { |
824 | try | 870 | try |
825 | { | 871 | { |
826 | int landID = m_landIDList[x / landUnit, y / landUnit]; | 872 | int landID = m_landIDList[x / LandUnit, y / LandUnit]; |
827 | if (landID == 0) | 873 | if (landID == 0) |
828 | { | 874 | { |
829 | // Zero is the uninitialized value saying there is no parcel for this location. | 875 | // Zero is the uninitialized value saying there is no parcel for this location. |
@@ -856,7 +902,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
856 | newLand.SetLandBitmap(CreateBitmapForID(0)); | 902 | newLand.SetLandBitmap(CreateBitmapForID(0)); |
857 | newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 903 | newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
858 | newLand.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); | 904 | newLand.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); |
859 | AddLandObject(newLand); | 905 | newLand = AddLandObject(newLand); |
906 | |||
907 | if (newLand == null) | ||
908 | return null; | ||
909 | |||
860 | landID = m_lastLandLocalID; | 910 | landID = m_lastLandLocalID; |
861 | } | 911 | } |
862 | } | 912 | } |
@@ -868,16 +918,19 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
868 | m_log.ErrorFormat( | 918 | m_log.ErrorFormat( |
869 | "{0} GetLandObject: Tried to retrieve land object from out of bounds co-ordinate ({1},{2}) in {3}. landListSize=({4},{5})", | 919 | "{0} GetLandObject: Tried to retrieve land object from out of bounds co-ordinate ({1},{2}) in {3}. landListSize=({4},{5})", |
870 | LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList.GetLength(0), m_landIDList.GetLength(1)); | 920 | LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList.GetLength(0), m_landIDList.GetLength(1)); |
921 | |||
871 | return null; | 922 | return null; |
872 | } | 923 | } |
873 | catch | 924 | catch |
874 | { | 925 | { |
875 | m_log.ErrorFormat( | 926 | m_log.ErrorFormat( |
876 | "{0} GetLandObject: LandID not in landlist. XY=<{1},{2}> in {3}. landID[x,y]={4}", | 927 | "{0} GetLandObject: LandID not in landlist. XY=<{1},{2}> in {3}. landID[x,y]={4}", |
877 | LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList[x/landUnit, y/landUnit]); | 928 | LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList[x/LandUnit, y/LandUnit]); |
929 | |||
878 | return null; | 930 | return null; |
879 | } | 931 | } |
880 | } | 932 | } |
933 | |||
881 | return ret; | 934 | return ret; |
882 | } | 935 | } |
883 | 936 | ||
@@ -1062,8 +1115,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1062 | 1115 | ||
1063 | //Now add the new land object | 1116 | //Now add the new land object |
1064 | ILandObject result = AddLandObject(newLand); | 1117 | ILandObject result = AddLandObject(newLand); |
1065 | UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); | 1118 | |
1066 | result.SendLandUpdateToAvatarsOverMe(); | 1119 | if (result != null) |
1120 | { | ||
1121 | UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); | ||
1122 | result.SendLandUpdateToAvatarsOverMe(); | ||
1123 | } | ||
1067 | } | 1124 | } |
1068 | 1125 | ||
1069 | /// <summary> | 1126 | /// <summary> |
@@ -1157,11 +1214,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1157 | int sequenceID = 0; | 1214 | int sequenceID = 0; |
1158 | 1215 | ||
1159 | // Layer data is in landUnit (4m) chunks | 1216 | // Layer data is in landUnit (4m) chunks |
1160 | for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); y++) | 1217 | for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++) |
1161 | { | 1218 | { |
1162 | for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); x++) | 1219 | for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++) |
1163 | { | 1220 | { |
1164 | byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * landUnit, y * landUnit), x, y, remote_client); | 1221 | byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * LandUnit, y * LandUnit), x, y, remote_client); |
1165 | byteArrayCount++; | 1222 | byteArrayCount++; |
1166 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) | 1223 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) |
1167 | { | 1224 | { |
@@ -1214,11 +1271,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1214 | ILandObject southParcel = null; | 1271 | ILandObject southParcel = null; |
1215 | if (x > 0) | 1272 | if (x > 0) |
1216 | { | 1273 | { |
1217 | westParcel = GetLandObject((x - 1) * landUnit, y * landUnit); | 1274 | westParcel = GetLandObject((x - 1) * LandUnit, y * LandUnit); |
1218 | } | 1275 | } |
1219 | if (y > 0) | 1276 | if (y > 0) |
1220 | { | 1277 | { |
1221 | southParcel = GetLandObject(x * landUnit, (y - 1) * landUnit); | 1278 | southParcel = GetLandObject(x * LandUnit, (y - 1) * LandUnit); |
1222 | } | 1279 | } |
1223 | 1280 | ||
1224 | if (x == 0) | 1281 | if (x == 0) |