aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs304
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs174
2 files changed, 295 insertions, 183 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 51ed83f..3f21f85 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -65,6 +65,7 @@ namespace OpenSim.Region.CoreModules.World.Land
65 public class LandManagementModule : INonSharedRegionModule 65 public class LandManagementModule : INonSharedRegionModule
66 { 66 {
67 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 67 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
68 private static readonly string LogHeader = "[LAND MANAGEMENT MODULE]";
68 69
69 private static readonly string remoteParcelRequestPath = "0009/"; 70 private static readonly string remoteParcelRequestPath = "0009/";
70 71
@@ -76,15 +77,11 @@ namespace OpenSim.Region.CoreModules.World.Land
76 protected IPrimCountModule m_primCountModule; 77 protected IPrimCountModule m_primCountModule;
77 protected IDialogModule m_Dialog; 78 protected IDialogModule m_Dialog;
78 79
79 // Minimum for parcels to work is 64m even if we don't actually use them.
80 #pragma warning disable 0429
81 private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
82 #pragma warning restore 0429
83
84 /// <value> 80 /// <value>
85 /// Local land ids at specified region co-ordinates (region size / 4) 81 /// Local land ids at specified region co-ordinates (region size / 4)
86 /// </value> 82 /// </value>
87 private readonly int[,] m_landIDList = new int[landArrayMax, landArrayMax]; 83 private int[,] m_landIDList;
84 private const int landUnit = 4;
88 85
89 /// <value> 86 /// <value>
90 /// Land objects keyed by local id 87 /// Land objects keyed by local id
@@ -117,6 +114,8 @@ namespace OpenSim.Region.CoreModules.World.Land
117 public void AddRegion(Scene scene) 114 public void AddRegion(Scene scene)
118 { 115 {
119 m_scene = scene; 116 m_scene = scene;
117 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
118
120 m_landIDList.Initialize(); 119 m_landIDList.Initialize();
121 landChannel = new LandChannel(scene, this); 120 landChannel = new LandChannel(scene, this);
122 121
@@ -326,6 +325,7 @@ namespace OpenSim.Region.CoreModules.World.Land
326 { 325 {
327 m_landList.Clear(); 326 m_landList.Clear();
328 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 327 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
328 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
329 m_landIDList.Initialize(); 329 m_landIDList.Initialize();
330 } 330 }
331 } 331 }
@@ -340,7 +340,8 @@ namespace OpenSim.Region.CoreModules.World.Land
340 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 340 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
341 341
342 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 342 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
343 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 343 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
344 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
344 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 345 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
345 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 346 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
346 347
@@ -467,8 +468,8 @@ namespace OpenSim.Region.CoreModules.World.Land
467 468
468 public void SendLandUpdate(ScenePresence avatar, bool force) 469 public void SendLandUpdate(ScenePresence avatar, bool force)
469 { 470 {
470 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 471 ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
471 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 472 (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
472 473
473 if (over != null) 474 if (over != null)
474 { 475 {
@@ -634,17 +635,29 @@ namespace OpenSim.Region.CoreModules.World.Land
634 new_land.LandData.LocalID = newLandLocalID; 635 new_land.LandData.LocalID = newLandLocalID;
635 636
636 bool[,] landBitmap = new_land.GetLandBitmap(); 637 bool[,] landBitmap = new_land.GetLandBitmap();
637 for (int x = 0; x < landArrayMax; x++) 638 m_log.DebugFormat("{0} AddLandObject. new_land.bitmapSize=({1},{2}). bitmap[600/4,600/4]={3}, newLocalID={4}",
639 LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), landBitmap[600/4, 600/4], newLandLocalID);
640
641 if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
642 {
643 // Going to variable sized regions can cause mismatches
644 m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})",
645 LogHeader, landBitmap.GetLength(0), m_landIDList.GetLength(1), landBitmap.GetLength(0), m_landIDList.GetLength(1) );
646 }
647 else
638 { 648 {
639 for (int y = 0; y < landArrayMax; y++) 649 for (int x = 0; x < landBitmap.GetLength(0); x++)
640 { 650 {
641 if (landBitmap[x, y]) 651 for (int y = 0; y < landBitmap.GetLength(1); y++)
642 { 652 {
643// m_log.DebugFormat( 653 if (landBitmap[x, y])
644// "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", 654 {
645// new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName); 655 // m_log.DebugFormat(
646 656 // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
647 m_landIDList[x, y] = newLandLocalID; 657 // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
658
659 m_landIDList[x, y] = newLandLocalID;
660 }
648 } 661 }
649 } 662 }
650 } 663 }
@@ -666,9 +679,9 @@ namespace OpenSim.Region.CoreModules.World.Land
666 ILandObject land; 679 ILandObject land;
667 lock (m_landList) 680 lock (m_landList)
668 { 681 {
669 for (int x = 0; x < 64; x++) 682 for (int x = 0; x < m_landIDList.GetLength(0); x++)
670 { 683 {
671 for (int y = 0; y < 64; y++) 684 for (int y = 0; y < m_landIDList.GetLength(1); y++)
672 { 685 {
673 if (m_landIDList[x, y] == local_id) 686 if (m_landIDList[x, y] == local_id)
674 { 687 {
@@ -720,9 +733,9 @@ namespace OpenSim.Region.CoreModules.World.Land
720 bool[,] landBitmapSlave = slave.GetLandBitmap(); 733 bool[,] landBitmapSlave = slave.GetLandBitmap();
721 lock (m_landList) 734 lock (m_landList)
722 { 735 {
723 for (int x = 0; x < 64; x++) 736 for (int x = 0; x < landBitmapSlave.GetLength(0); x++)
724 { 737 {
725 for (int y = 0; y < 64; y++) 738 for (int y = 0; y < landBitmapSlave.GetLength(1); y++)
726 { 739 {
727 if (landBitmapSlave[x, y]) 740 if (landBitmapSlave[x, y])
728 { 741 {
@@ -756,23 +769,28 @@ namespace OpenSim.Region.CoreModules.World.Land
756 /// <returns>Land object at the point supplied</returns> 769 /// <returns>Land object at the point supplied</returns>
757 public ILandObject GetLandObject(float x_float, float y_float) 770 public ILandObject GetLandObject(float x_float, float y_float)
758 { 771 {
772 return GetLandObject((int)x_float, (int)y_float);
773 /*
759 int x; 774 int x;
760 int y; 775 int y;
761 776
762 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 777 if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0)
763 return null; 778 return null;
764 779
765 try 780 try
766 { 781 {
767 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0)); 782 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit));
768 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / 4.0)); 783 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit));
769 } 784 }
770 catch (OverflowException) 785 catch (OverflowException)
771 { 786 {
772 return null; 787 return null;
773 } 788 }
774 789
775 if (x >= 64 || y >= 64 || x < 0 || y < 0) 790 if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit)
791 || y >= (m_scene.RegionInfo.RegionSizeY / landUnit)
792 || x < 0
793 || y < 0)
776 { 794 {
777 return null; 795 return null;
778 } 796 }
@@ -788,38 +806,112 @@ namespace OpenSim.Region.CoreModules.World.Land
788// m_log.DebugFormat( 806// m_log.DebugFormat(
789// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}", 807// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
790// x, y, m_scene.RegionInfo.RegionName); 808// x, y, m_scene.RegionInfo.RegionName);
791 809
792 if (m_landList.ContainsKey(m_landIDList[x, y])) 810 try
793 return m_landList[m_landIDList[x, y]]; 811 {
812 if (m_landList.ContainsKey(m_landIDList[x, y]))
813 return m_landList[m_landIDList[x, y]];
814 }
815 catch (Exception e)
816 {
817 m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})",
818 LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
819 }
794 820
795 return null; 821 return null;
796 } 822 }
823 */
797 } 824 }
798 825
826 // Given a region position, return the parcel land object for that location
799 public ILandObject GetLandObject(int x, int y) 827 public ILandObject GetLandObject(int x, int y)
800 { 828 {
801 if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0) 829 ILandObject ret = null;
830
831 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
802 { 832 {
803 // These exceptions here will cause a lot of complaints from the users specifically because 833 // These exceptions here will cause a lot of complaints from the users specifically because
804 // they happen every time at border crossings 834 // they happen every time at border crossings
805 throw new Exception("Error: Parcel not found at point " + x + ", " + y); 835 throw new Exception(
836 String.Format("{0} GetLandObject for non-existant position. Region={1}, pos=<{2},{3}",
837 LogHeader, m_scene.RegionInfo.RegionName, x, y)
838 );
806 } 839 }
807 840
808 lock (m_landIDList) 841 lock (m_landIDList)
809 { 842 {
810 try 843 try
811 { 844 {
812 return m_landList[m_landIDList[x / 4, y / 4]]; 845 int landID = m_landIDList[x / landUnit, y / landUnit];
846 if (landID == 0)
847 {
848 // Zero is the uninitialized value saying there is no parcel for this location.
849 // This sometimes happens when terrain is resized.
850 if (m_landList.Count == 1)
851 {
852 int onlyParcelID = 0;
853 ILandObject onlyLandObject = null;
854 foreach (KeyValuePair<int, ILandObject> kvp in m_landList)
855 {
856 onlyParcelID = kvp.Key;
857 onlyLandObject = kvp.Value;
858 break;
859 }
860
861 // There is only one parcel. Grow it to fill all the unallocated spaces.
862 for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
863 for (int yy = 0; yy < m_landIDList.GetLength(1); yy++)
864 if (m_landIDList[xx, yy] == 0)
865 m_landIDList[xx, yy] = onlyParcelID;
866
867 onlyLandObject.LandBitmap = CreateBitmapForID(onlyParcelID);
868 landID = onlyParcelID;
869 }
870 else
871 {
872 // There are several other parcels so we must create a new one for the unassigned space
873 ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
874 // Claim all the unclaimed "0" ids
875 newLand.SetLandBitmap(CreateBitmapForID(0));
876 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
877 newLand.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
878 AddLandObject(newLand);
879 landID = m_lastLandLocalID;
880 }
881 }
882
883 ret = m_landList[landID];
813 } 884 }
814 catch (IndexOutOfRangeException) 885 catch (IndexOutOfRangeException)
815 { 886 {
816// m_log.WarnFormat( 887 m_log.ErrorFormat(
817// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}", 888 "{0} GetLandObject: Tried to retrieve land object from out of bounds co-ordinate ({1},{2}) in {3}. landListSize=({4},{5})",
818// x, y, m_scene.RegionInfo.RegionName); 889 LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
819 890 return null;
891 }
892 catch
893 {
894 m_log.ErrorFormat(
895 "{0} GetLandObject: LandID not in landlist. XY=<{1},{2}> in {3}. landID[x,y]={4}",
896 LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList[x/landUnit, y/landUnit]);
820 return null; 897 return null;
821 } 898 }
822 } 899 }
900 return ret;
901 }
902
903 // Create a 'parcel is here' bitmap for the parcel identified by the passed landID
904 private bool[,] CreateBitmapForID(int landID)
905 {
906 bool[,] ret = new bool[m_landIDList.GetLength(0), m_landIDList.GetLength(1)];
907 ret.Initialize();
908
909 for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
910 for (int yy = 0; yy < m_landIDList.GetLength(0); yy++)
911 if (m_landIDList[xx, yy] == landID)
912 ret[xx, yy] = true;
913
914 return ret;
823 } 915 }
824 916
825 #endregion 917 #endregion
@@ -1082,85 +1174,93 @@ namespace OpenSim.Region.CoreModules.World.Land
1082 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1174 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1083 int byteArrayCount = 0; 1175 int byteArrayCount = 0;
1084 int sequenceID = 0; 1176 int sequenceID = 0;
1085 int blockmeters = 4 * (int) Constants.RegionSize/(int)Constants.TerrainPatchSize;
1086 1177
1087 1178 // Layer data is in landUnit (4m) chunks
1088 for (int y = 0; y < blockmeters; y++) 1179 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); y++)
1089 { 1180 {
1090 for (int x = 0; x < blockmeters; x++) 1181 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); x++)
1091 { 1182 {
1092 byte tempByte = 0; //This represents the byte for the current 4x4 1183 byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * landUnit, y * landUnit), x, y, remote_client);
1184 byteArrayCount++;
1185 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
1186 {
1187 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1188 byteArrayCount = 0;
1189 sequenceID++;
1190 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1191 }
1093 1192
1094 ILandObject currentParcelBlock = GetLandObject(x * 4, y * 4); 1193 }
1194 }
1195 if (byteArrayCount != 0)
1196 {
1197 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1198 }
1199 }
1095 1200
1096 if (currentParcelBlock != null) 1201 private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client)
1097 { 1202 {
1098 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) 1203 byte tempByte = 0; //This represents the byte for the current 4x4
1099 {
1100 //Owner Flag
1101 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1102 }
1103 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1104 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1105 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1106 {
1107 //Sale Flag
1108 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
1109 }
1110 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1111 {
1112 //Public Flag
1113 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
1114 }
1115 else
1116 {
1117 //Other Flag
1118 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
1119 }
1120 1204
1121 //Now for border control 1205 if (currentParcelBlock != null)
1206 {
1207 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
1208 {
1209 //Owner Flag
1210 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1211 }
1212 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1213 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1214 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1215 {
1216 //Sale Flag
1217 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
1218 }
1219 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1220 {
1221 //Public Flag
1222 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
1223 }
1224 else
1225 {
1226 //Other Flag
1227 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
1228 }
1122 1229
1123 ILandObject westParcel = null; 1230 //Now for border control
1124 ILandObject southParcel = null;
1125 if (x > 0)
1126 {
1127 westParcel = GetLandObject((x - 1) * 4, y * 4);
1128 }
1129 if (y > 0)
1130 {
1131 southParcel = GetLandObject(x * 4, (y - 1) * 4);
1132 }
1133 1231
1134 if (x == 0) 1232 ILandObject westParcel = null;
1135 { 1233 ILandObject southParcel = null;
1136 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); 1234 if (x > 0)
1137 } 1235 {
1138 else if (westParcel != null && westParcel != currentParcelBlock) 1236 westParcel = GetLandObject((x - 1) * landUnit, y * landUnit);
1139 { 1237 }
1140 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); 1238 if (y > 0)
1141 } 1239 {
1240 southParcel = GetLandObject(x * landUnit, (y - 1) * landUnit);
1241 }
1142 1242
1143 if (y == 0) 1243 if (x == 0)
1144 { 1244 {
1145 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1245 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1146 } 1246 }
1147 else if (southParcel != null && southParcel != currentParcelBlock) 1247 else if (westParcel != null && westParcel != currentParcelBlock)
1148 { 1248 {
1149 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1249 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1150 } 1250 }
1151 1251
1152 byteArray[byteArrayCount] = tempByte; 1252 if (y == 0)
1153 byteArrayCount++; 1253 {
1154 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) 1254 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
1155 { 1255 }
1156 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1256 else if (southParcel != null && southParcel != currentParcelBlock)
1157 byteArrayCount = 0; 1257 {
1158 sequenceID++; 1258 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
1159 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1160 }
1161 }
1162 } 1259 }
1260
1163 } 1261 }
1262
1263 return tempByte;
1164 } 1264 }
1165 1265
1166 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, 1266 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index e55c9ed..0bde877 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -45,10 +45,10 @@ namespace OpenSim.Region.CoreModules.World.Land
45 #region Member Variables 45 #region Member Variables
46 46
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 #pragma warning disable 0429 48 private static readonly string LogHeader = "[LAND OBJECT]";
49 private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; 49
50 #pragma warning restore 0429 50 private bool[,] m_landBitmap;
51 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; 51 private readonly int landUnit = 4;
52 52
53 private int m_lastSeqId = 0; 53 private int m_lastSeqId = 0;
54 54
@@ -93,12 +93,12 @@ namespace OpenSim.Region.CoreModules.World.Land
93 { 93 {
94 get 94 get
95 { 95 {
96 for (int y = 0; y < landArrayMax; y++) 96 for (int y = 0; y < LandBitmap.GetLength(1); y++)
97 { 97 {
98 for (int x = 0; x < landArrayMax; x++) 98 for (int x = 0; x < LandBitmap.GetLength(0); x++)
99 { 99 {
100 if (LandBitmap[x, y]) 100 if (LandBitmap[x, y])
101 return new Vector3(x * 4, y * 4, 0); 101 return new Vector3(x * landUnit, y * landUnit, 0);
102 } 102 }
103 } 103 }
104 104
@@ -110,13 +110,13 @@ namespace OpenSim.Region.CoreModules.World.Land
110 { 110 {
111 get 111 get
112 { 112 {
113 for (int y = landArrayMax - 1; y >= 0; y--) 113 for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--)
114 { 114 {
115 for (int x = landArrayMax - 1; x >= 0; x--) 115 for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--)
116 { 116 {
117 if (LandBitmap[x, y]) 117 if (LandBitmap[x, y])
118 { 118 {
119 return new Vector3(x * 4 + 4, y * 4 + 4, 0); 119 return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0);
120 } 120 }
121 } 121 }
122 } 122 }
@@ -130,6 +130,8 @@ namespace OpenSim.Region.CoreModules.World.Land
130 public LandObject(UUID owner_id, bool is_group_owned, Scene scene) 130 public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
131 { 131 {
132 m_scene = scene; 132 m_scene = scene;
133 m_landBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
134
133 LandData.OwnerID = owner_id; 135 LandData.OwnerID = owner_id;
134 if (is_group_owned) 136 if (is_group_owned)
135 LandData.GroupID = owner_id; 137 LandData.GroupID = owner_id;
@@ -152,9 +154,9 @@ namespace OpenSim.Region.CoreModules.World.Land
152 /// <returns>Returns true if the piece of land contains the specified point</returns> 154 /// <returns>Returns true if the piece of land contains the specified point</returns>
153 public bool ContainsPoint(int x, int y) 155 public bool ContainsPoint(int x, int y)
154 { 156 {
155 if (x >= 0 && y >= 0 && x < Constants.RegionSize && y < Constants.RegionSize) 157 if (x >= 0 && y >= 0 && x < m_scene.RegionInfo.RegionSizeX && y < m_scene.RegionInfo.RegionSizeY)
156 { 158 {
157 return (LandBitmap[x / 4, y / 4] == true); 159 return (LandBitmap[x / landUnit, y / landUnit] == true);
158 } 160 }
159 else 161 else
160 { 162 {
@@ -194,7 +196,7 @@ namespace OpenSim.Region.CoreModules.World.Land
194 else 196 else
195 { 197 {
196 // Normal Calculations 198 // Normal Calculations
197 int parcelMax = (int)(((float)LandData.Area / 65536.0f) 199 int parcelMax = (int)(((float)LandData.Area / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
198 * (float)m_scene.RegionInfo.ObjectCapacity 200 * (float)m_scene.RegionInfo.ObjectCapacity
199 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 201 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
200 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! 202 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL!
@@ -211,7 +213,7 @@ namespace OpenSim.Region.CoreModules.World.Land
211 else 213 else
212 { 214 {
213 //Normal Calculations 215 //Normal Calculations
214 int simMax = (int)(((float)LandData.SimwideArea / 65536.0f) 216 int simMax = (int)(((float)LandData.SimwideArea / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
215 * (float)m_scene.RegionInfo.ObjectCapacity); 217 * (float)m_scene.RegionInfo.ObjectCapacity);
216 return simMax; 218 return simMax;
217 } 219 }
@@ -224,7 +226,12 @@ namespace OpenSim.Region.CoreModules.World.Land
224 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) 226 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
225 { 227 {
226 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 228 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
227 uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); 229 // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
230 uint regionFlags = (uint)(RegionFlags.PublicAllowed
231 | RegionFlags.AllowDirectTeleport
232 | RegionFlags.AllowParcelChanges
233 | RegionFlags.AllowVoice );
234
228 if (estateModule != null) 235 if (estateModule != null)
229 regionFlags = estateModule.GetRegionFlags(); 236 regionFlags = estateModule.GetRegionFlags();
230 237
@@ -546,8 +553,8 @@ namespace OpenSim.Region.CoreModules.World.Land
546 try 553 try
547 { 554 {
548 over = 555 over =
549 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), 556 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)),
550 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); 557 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1)));
551 } 558 }
552 catch (Exception) 559 catch (Exception)
553 { 560 {
@@ -694,15 +701,15 @@ namespace OpenSim.Region.CoreModules.World.Land
694 /// </summary> 701 /// </summary>
695 private void UpdateAABBAndAreaValues() 702 private void UpdateAABBAndAreaValues()
696 { 703 {
697 int min_x = 64; 704 int min_x = 10000;
698 int min_y = 64; 705 int min_y = 10000;
699 int max_x = 0; 706 int max_x = 0;
700 int max_y = 0; 707 int max_y = 0;
701 int tempArea = 0; 708 int tempArea = 0;
702 int x, y; 709 int x, y;
703 for (x = 0; x < 64; x++) 710 for (x = 0; x < LandBitmap.GetLength(0); x++)
704 { 711 {
705 for (y = 0; y < 64; y++) 712 for (y = 0; y < LandBitmap.GetLength(1); y++)
706 { 713 {
707 if (LandBitmap[x, y] == true) 714 if (LandBitmap[x, y] == true)
708 { 715 {
@@ -710,31 +717,31 @@ namespace OpenSim.Region.CoreModules.World.Land
710 if (min_y > y) min_y = y; 717 if (min_y > y) min_y = y;
711 if (max_x < x) max_x = x; 718 if (max_x < x) max_x = x;
712 if (max_y < y) max_y = y; 719 if (max_y < y) max_y = y;
713 tempArea += 16; //16sqm peice of land 720 tempArea += landUnit * landUnit; //16sqm peice of land
714 } 721 }
715 } 722 }
716 } 723 }
717 int tx = min_x * 4; 724 int tx = min_x * landUnit;
718 if (tx > ((int)Constants.RegionSize - 1)) 725 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
719 tx = ((int)Constants.RegionSize - 1); 726 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
720 int ty = min_y * 4; 727 int ty = min_y * landUnit;
721 if (ty > ((int)Constants.RegionSize - 1)) 728 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
722 ty = ((int)Constants.RegionSize - 1); 729 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
723 730
724 LandData.AABBMin = 731 LandData.AABBMin =
725 new Vector3( 732 new Vector3(
726 (float)(min_x * 4), (float)(min_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 733 (float)(min_x * landUnit), (float)(min_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
727 734
728 tx = max_x * 4; 735 tx = max_x * landUnit;
729 if (tx > ((int)Constants.RegionSize - 1)) 736 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
730 tx = ((int)Constants.RegionSize - 1); 737 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
731 ty = max_y * 4; 738 ty = max_y * landUnit;
732 if (ty > ((int)Constants.RegionSize - 1)) 739 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
733 ty = ((int)Constants.RegionSize - 1); 740 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
734 741
735 LandData.AABBMax 742 LandData.AABBMax
736 = new Vector3( 743 = new Vector3(
737 (float)(max_x * 4), (float)(max_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 744 (float)(max_x * landUnit), (float)(max_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
738 745
739 LandData.Area = tempArea; 746 LandData.Area = tempArea;
740 } 747 }
@@ -746,20 +753,11 @@ namespace OpenSim.Region.CoreModules.World.Land
746 /// <summary> 753 /// <summary>
747 /// Sets the land's bitmap manually 754 /// Sets the land's bitmap manually
748 /// </summary> 755 /// </summary>
749 /// <param name="bitmap">64x64 block representing where this land is on a map</param> 756 /// <param name="bitmap">block representing where this land is on a map mapped in a 4x4 meter grid</param>
750 public void SetLandBitmap(bool[,] bitmap) 757 public void SetLandBitmap(bool[,] bitmap)
751 { 758 {
752 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) 759 LandBitmap = bitmap;
753 { 760 ForceUpdateLandInfo();
754 //Throw an exception - The bitmap is not 64x64
755 //throw new Exception("Error: Invalid Parcel Bitmap");
756 }
757 else
758 {
759 //Valid: Lets set it
760 LandBitmap = bitmap;
761 ForceUpdateLandInfo();
762 }
763 } 761 }
764 762
765 /// <summary> 763 /// <summary>
@@ -773,12 +771,12 @@ namespace OpenSim.Region.CoreModules.World.Land
773 771
774 public bool[,] BasicFullRegionLandBitmap() 772 public bool[,] BasicFullRegionLandBitmap()
775 { 773 {
776 return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); 774 return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY);
777 } 775 }
778 776
779 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) 777 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
780 { 778 {
781 bool[,] tempBitmap = new bool[64,64]; 779 bool[,] tempBitmap = new bool[(end_x-start_x)/landUnit,(end_y-start_y)/landUnit];
782 tempBitmap.Initialize(); 780 tempBitmap.Initialize();
783 781
784 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); 782 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
@@ -798,19 +796,13 @@ namespace OpenSim.Region.CoreModules.World.Land
798 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, 796 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
799 bool set_value) 797 bool set_value)
800 { 798 {
801 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
802 {
803 //Throw an exception - The bitmap is not 64x64
804 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
805 }
806
807 int x, y; 799 int x, y;
808 for (y = 0; y < 64; y++) 800 for (y = 0; y < land_bitmap.GetLength(1); y++)
809 { 801 {
810 for (x = 0; x < 64; x++) 802 for (x = 0; x < land_bitmap.GetLength(0); x++)
811 { 803 {
812 if (x >= start_x / 4 && x < end_x / 4 804 if (x >= start_x / landUnit && x < end_x / landUnit
813 && y >= start_y / 4 && y < end_y / 4) 805 && y >= start_y / landUnit && y < end_y / landUnit)
814 { 806 {
815 land_bitmap[x, y] = set_value; 807 land_bitmap[x, y] = set_value;
816 } 808 }
@@ -827,21 +819,21 @@ namespace OpenSim.Region.CoreModules.World.Land
827 /// <returns></returns> 819 /// <returns></returns>
828 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) 820 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
829 { 821 {
830 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) 822 if (bitmap_base.GetLength(0) != bitmap_add.GetLength(0)
823 || bitmap_base.GetLength(1) != bitmap_add.GetLength(1)
824 || bitmap_add.Rank != 2
825 || bitmap_base.Rank != 2)
831 { 826 {
832 //Throw an exception - The bitmap is not 64x64 827 throw new Exception(
833 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); 828 String.Format("{0} MergeLandBitmaps. merging maps not same size. baseSizeXY=<{1},{2}>, addSizeXY=<{3},{4}>",
834 } 829 LogHeader, bitmap_base.GetLength(0), bitmap_base.GetLength(1), bitmap_add.GetLength(0), bitmap_add.GetLength(1))
835 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) 830 );
836 {
837 //Throw an exception - The bitmap is not 64x64
838 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
839 } 831 }
840 832
841 int x, y; 833 int x, y;
842 for (y = 0; y < 64; y++) 834 for (y = 0; y < bitmap_base.GetLength(1); y++)
843 { 835 {
844 for (x = 0; x < 64; x++) 836 for (x = 0; x < bitmap_add.GetLength(0); x++)
845 { 837 {
846 if (bitmap_add[x, y]) 838 if (bitmap_add[x, y])
847 { 839 {
@@ -858,13 +850,13 @@ namespace OpenSim.Region.CoreModules.World.Land
858 /// <returns></returns> 850 /// <returns></returns>
859 private byte[] ConvertLandBitmapToBytes() 851 private byte[] ConvertLandBitmapToBytes()
860 { 852 {
861 byte[] tempConvertArr = new byte[512]; 853 byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
862 byte tempByte = 0; 854 byte tempByte = 0;
863 int x, y, i, byteNum = 0; 855 int byteNum = 0;
864 i = 0; 856 int i = 0;
865 for (y = 0; y < 64; y++) 857 for (int y = 0; y < LandBitmap.GetLength(1); y++)
866 { 858 {
867 for (x = 0; x < 64; x++) 859 for (int x = 0; x < LandBitmap.GetLength(0); x++)
868 { 860 {
869 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); 861 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
870 if (i % 8 == 0) 862 if (i % 8 == 0)
@@ -881,25 +873,45 @@ namespace OpenSim.Region.CoreModules.World.Land
881 873
882 private bool[,] ConvertBytesToLandBitmap() 874 private bool[,] ConvertBytesToLandBitmap()
883 { 875 {
884 bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; 876 bool[,] tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
885 tempConvertMap.Initialize(); 877 tempConvertMap.Initialize();
886 byte tempByte = 0; 878 byte tempByte = 0;
887 int x = 0, y = 0, i = 0, bitNum = 0; 879 // Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
888 for (i = 0; i < 512; i++) 880 int bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8);
881 int xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit);
882
883 if (bitmapLen == 512)
884 {
885 // Legacy bitmap being passed in. Use the legacy region size
886 // and only set the lower area of the larger region.
887 xLen = (int)(Constants.RegionSize / landUnit);
888 }
889 m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen);
890
891 int x = 0, y = 0;
892 for (int i = 0; i < bitmapLen; i++)
889 { 893 {
890 tempByte = LandData.Bitmap[i]; 894 tempByte = LandData.Bitmap[i];
891 for (bitNum = 0; bitNum < 8; bitNum++) 895 for (int bitNum = 0; bitNum < 8; bitNum++)
892 { 896 {
893 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); 897 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
894 tempConvertMap[x, y] = bit; 898 try
899 {
900 tempConvertMap[x, y] = bit;
901 }
902 catch (Exception e)
903 {
904 m_log.DebugFormat("{0} ConvertBytestoLandBitmap: i={1}, x={2}, y={3}", LogHeader, i, x, y);
905 }
895 x++; 906 x++;
896 if (x > 63) 907 if (x >= xLen)
897 { 908 {
898 x = 0; 909 x = 0;
899 y++; 910 y++;
900 } 911 }
901 } 912 }
902 } 913 }
914
903 return tempConvertMap; 915 return tempConvertMap;
904 } 916 }
905 917