diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 51ed83f43c..3f21f85ddd 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
public class LandManagementModule : INonSharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static readonly string LogHeader = "[LAND MANAGEMENT MODULE]";
private static readonly string remoteParcelRequestPath = "0009/";
@@ -76,15 +77,11 @@ namespace OpenSim.Region.CoreModules.World.Land
protected IPrimCountModule m_primCountModule;
protected IDialogModule m_Dialog;
- // Minimum for parcels to work is 64m even if we don't actually use them.
- #pragma warning disable 0429
- private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
- #pragma warning restore 0429
-
///
/// Local land ids at specified region co-ordinates (region size / 4)
///
- private readonly int[,] m_landIDList = new int[landArrayMax, landArrayMax];
+ private int[,] m_landIDList;
+ private const int landUnit = 4;
///
/// Land objects keyed by local id
@@ -117,6 +114,8 @@ namespace OpenSim.Region.CoreModules.World.Land
public void AddRegion(Scene scene)
{
m_scene = scene;
+ m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
+
m_landIDList.Initialize();
landChannel = new LandChannel(scene, this);
@@ -326,6 +325,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
m_landList.Clear();
m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
+ m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
m_landIDList.Initialize();
}
}
@@ -340,7 +340,8 @@ namespace OpenSim.Region.CoreModules.World.Land
"[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
- fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
+ fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
+ (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
@@ -467,8 +468,8 @@ namespace OpenSim.Region.CoreModules.World.Land
public void SendLandUpdate(ScenePresence avatar, bool force)
{
- ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
- (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
+ ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
+ (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
if (over != null)
{
@@ -634,17 +635,29 @@ namespace OpenSim.Region.CoreModules.World.Land
new_land.LandData.LocalID = newLandLocalID;
bool[,] landBitmap = new_land.GetLandBitmap();
- for (int x = 0; x < landArrayMax; x++)
+ m_log.DebugFormat("{0} AddLandObject. new_land.bitmapSize=({1},{2}). bitmap[600/4,600/4]={3}, newLocalID={4}",
+ LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), landBitmap[600/4, 600/4], newLandLocalID);
+
+ if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
{
- for (int y = 0; y < landArrayMax; y++)
+ // Going to variable sized regions can cause mismatches
+ m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})",
+ LogHeader, landBitmap.GetLength(0), m_landIDList.GetLength(1), landBitmap.GetLength(0), m_landIDList.GetLength(1) );
+ }
+ else
+ {
+ for (int x = 0; x < landBitmap.GetLength(0); x++)
{
- if (landBitmap[x, y])
+ for (int y = 0; y < landBitmap.GetLength(1); y++)
{
-// m_log.DebugFormat(
-// "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
-// new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
-
- m_landIDList[x, y] = newLandLocalID;
+ if (landBitmap[x, y])
+ {
+ // m_log.DebugFormat(
+ // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
+ // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
+
+ m_landIDList[x, y] = newLandLocalID;
+ }
}
}
}
@@ -666,9 +679,9 @@ namespace OpenSim.Region.CoreModules.World.Land
ILandObject land;
lock (m_landList)
{
- for (int x = 0; x < 64; x++)
+ for (int x = 0; x < m_landIDList.GetLength(0); x++)
{
- for (int y = 0; y < 64; y++)
+ for (int y = 0; y < m_landIDList.GetLength(1); y++)
{
if (m_landIDList[x, y] == local_id)
{
@@ -720,9 +733,9 @@ namespace OpenSim.Region.CoreModules.World.Land
bool[,] landBitmapSlave = slave.GetLandBitmap();
lock (m_landList)
{
- for (int x = 0; x < 64; x++)
+ for (int x = 0; x < landBitmapSlave.GetLength(0); x++)
{
- for (int y = 0; y < 64; y++)
+ for (int y = 0; y < landBitmapSlave.GetLength(1); y++)
{
if (landBitmapSlave[x, y])
{
@@ -756,23 +769,28 @@ namespace OpenSim.Region.CoreModules.World.Land
/// Land object at the point supplied
public ILandObject GetLandObject(float x_float, float y_float)
{
+ return GetLandObject((int)x_float, (int)y_float);
+ /*
int x;
int y;
- if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0)
+ if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0)
return null;
try
{
- x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0));
- y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / 4.0));
+ x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit));
+ y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit));
}
catch (OverflowException)
{
return null;
}
- if (x >= 64 || y >= 64 || x < 0 || y < 0)
+ if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit)
+ || y >= (m_scene.RegionInfo.RegionSizeY / landUnit)
+ || x < 0
+ || y < 0)
{
return null;
}
@@ -788,38 +806,112 @@ namespace OpenSim.Region.CoreModules.World.Land
// m_log.DebugFormat(
// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
// x, y, m_scene.RegionInfo.RegionName);
-
- if (m_landList.ContainsKey(m_landIDList[x, y]))
- return m_landList[m_landIDList[x, y]];
+
+ try
+ {
+ if (m_landList.ContainsKey(m_landIDList[x, y]))
+ return m_landList[m_landIDList[x, y]];
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})",
+ LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
+ }
return null;
}
+ */
}
+ // Given a region position, return the parcel land object for that location
public ILandObject GetLandObject(int x, int y)
{
- if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0)
+ ILandObject ret = null;
+
+ if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
{
// These exceptions here will cause a lot of complaints from the users specifically because
// they happen every time at border crossings
- throw new Exception("Error: Parcel not found at point " + x + ", " + y);
+ throw new Exception(
+ String.Format("{0} GetLandObject for non-existant position. Region={1}, pos=<{2},{3}",
+ LogHeader, m_scene.RegionInfo.RegionName, x, y)
+ );
}
lock (m_landIDList)
{
try
{
- return m_landList[m_landIDList[x / 4, y / 4]];
+ int landID = m_landIDList[x / landUnit, y / landUnit];
+ if (landID == 0)
+ {
+ // Zero is the uninitialized value saying there is no parcel for this location.
+ // This sometimes happens when terrain is resized.
+ if (m_landList.Count == 1)
+ {
+ int onlyParcelID = 0;
+ ILandObject onlyLandObject = null;
+ foreach (KeyValuePair kvp in m_landList)
+ {
+ onlyParcelID = kvp.Key;
+ onlyLandObject = kvp.Value;
+ break;
+ }
+
+ // There is only one parcel. Grow it to fill all the unallocated spaces.
+ for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
+ for (int yy = 0; yy < m_landIDList.GetLength(1); yy++)
+ if (m_landIDList[xx, yy] == 0)
+ m_landIDList[xx, yy] = onlyParcelID;
+
+ onlyLandObject.LandBitmap = CreateBitmapForID(onlyParcelID);
+ landID = onlyParcelID;
+ }
+ else
+ {
+ // There are several other parcels so we must create a new one for the unassigned space
+ ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
+ // Claim all the unclaimed "0" ids
+ newLand.SetLandBitmap(CreateBitmapForID(0));
+ newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
+ newLand.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
+ AddLandObject(newLand);
+ landID = m_lastLandLocalID;
+ }
+ }
+
+ ret = m_landList[landID];
}
catch (IndexOutOfRangeException)
{
-// m_log.WarnFormat(
-// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}",
-// x, y, m_scene.RegionInfo.RegionName);
-
+ m_log.ErrorFormat(
+ "{0} GetLandObject: Tried to retrieve land object from out of bounds co-ordinate ({1},{2}) in {3}. landListSize=({4},{5})",
+ LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
+ return null;
+ }
+ catch
+ {
+ m_log.ErrorFormat(
+ "{0} GetLandObject: LandID not in landlist. XY=<{1},{2}> in {3}. landID[x,y]={4}",
+ LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList[x/landUnit, y/landUnit]);
return null;
}
}
+ return ret;
+ }
+
+ // Create a 'parcel is here' bitmap for the parcel identified by the passed landID
+ private bool[,] CreateBitmapForID(int landID)
+ {
+ bool[,] ret = new bool[m_landIDList.GetLength(0), m_landIDList.GetLength(1)];
+ ret.Initialize();
+
+ for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
+ for (int yy = 0; yy < m_landIDList.GetLength(0); yy++)
+ if (m_landIDList[xx, yy] == landID)
+ ret[xx, yy] = true;
+
+ return ret;
}
#endregion
@@ -1082,85 +1174,93 @@ namespace OpenSim.Region.CoreModules.World.Land
byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
int byteArrayCount = 0;
int sequenceID = 0;
- int blockmeters = 4 * (int) Constants.RegionSize/(int)Constants.TerrainPatchSize;
-
- for (int y = 0; y < blockmeters; y++)
+ // Layer data is in landUnit (4m) chunks
+ for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); y++)
{
- for (int x = 0; x < blockmeters; x++)
+ for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); x++)
{
- byte tempByte = 0; //This represents the byte for the current 4x4
-
- ILandObject currentParcelBlock = GetLandObject(x * 4, y * 4);
-
- if (currentParcelBlock != null)
+ byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * landUnit, y * landUnit), x, y, remote_client);
+ byteArrayCount++;
+ if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
{
- if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
- {
- //Owner Flag
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
- }
- else if (currentParcelBlock.LandData.SalePrice > 0 &&
- (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
- currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
- {
- //Sale Flag
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
- }
- else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
- {
- //Public Flag
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
- }
- else
- {
- //Other Flag
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
- }
-
- //Now for border control
-
- ILandObject westParcel = null;
- ILandObject southParcel = null;
- if (x > 0)
- {
- westParcel = GetLandObject((x - 1) * 4, y * 4);
- }
- if (y > 0)
- {
- southParcel = GetLandObject(x * 4, (y - 1) * 4);
- }
-
- if (x == 0)
- {
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
- }
- else if (westParcel != null && westParcel != currentParcelBlock)
- {
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
- }
-
- if (y == 0)
- {
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
- }
- else if (southParcel != null && southParcel != currentParcelBlock)
- {
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
- }
-
- byteArray[byteArrayCount] = tempByte;
- byteArrayCount++;
- if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
- {
- remote_client.SendLandParcelOverlay(byteArray, sequenceID);
- byteArrayCount = 0;
- sequenceID++;
- byteArray = new byte[LAND_BLOCKS_PER_PACKET];
- }
+ remote_client.SendLandParcelOverlay(byteArray, sequenceID);
+ byteArrayCount = 0;
+ sequenceID++;
+ byteArray = new byte[LAND_BLOCKS_PER_PACKET];
}
+
}
}
+ if (byteArrayCount != 0)
+ {
+ remote_client.SendLandParcelOverlay(byteArray, sequenceID);
+ }
+ }
+
+ private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client)
+ {
+ byte tempByte = 0; //This represents the byte for the current 4x4
+
+ if (currentParcelBlock != null)
+ {
+ if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
+ {
+ //Owner Flag
+ tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
+ }
+ else if (currentParcelBlock.LandData.SalePrice > 0 &&
+ (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
+ currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
+ {
+ //Sale Flag
+ tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
+ }
+ else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
+ {
+ //Public Flag
+ tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
+ }
+ else
+ {
+ //Other Flag
+ tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
+ }
+
+ //Now for border control
+
+ ILandObject westParcel = null;
+ ILandObject southParcel = null;
+ if (x > 0)
+ {
+ westParcel = GetLandObject((x - 1) * landUnit, y * landUnit);
+ }
+ if (y > 0)
+ {
+ southParcel = GetLandObject(x * landUnit, (y - 1) * landUnit);
+ }
+
+ if (x == 0)
+ {
+ tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
+ }
+ else if (westParcel != null && westParcel != currentParcelBlock)
+ {
+ tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
+ }
+
+ if (y == 0)
+ {
+ tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
+ }
+ else if (southParcel != null && southParcel != currentParcelBlock)
+ {
+ tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
+ }
+
+ }
+
+ return tempByte;
}
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 e55c9ed87f..0bde877ea1 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
#region Member Variables
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- #pragma warning disable 0429
- private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
- #pragma warning restore 0429
- private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax];
+ private static readonly string LogHeader = "[LAND OBJECT]";
+
+ private bool[,] m_landBitmap;
+ private readonly int landUnit = 4;
private int m_lastSeqId = 0;
@@ -93,12 +93,12 @@ namespace OpenSim.Region.CoreModules.World.Land
{
get
{
- for (int y = 0; y < landArrayMax; y++)
+ for (int y = 0; y < LandBitmap.GetLength(1); y++)
{
- for (int x = 0; x < landArrayMax; x++)
+ for (int x = 0; x < LandBitmap.GetLength(0); x++)
{
if (LandBitmap[x, y])
- return new Vector3(x * 4, y * 4, 0);
+ return new Vector3(x * landUnit, y * landUnit, 0);
}
}
@@ -110,13 +110,13 @@ namespace OpenSim.Region.CoreModules.World.Land
{
get
{
- for (int y = landArrayMax - 1; y >= 0; y--)
+ for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--)
{
- for (int x = landArrayMax - 1; x >= 0; x--)
+ for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--)
{
if (LandBitmap[x, y])
{
- return new Vector3(x * 4 + 4, y * 4 + 4, 0);
+ return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0);
}
}
}
@@ -130,6 +130,8 @@ namespace OpenSim.Region.CoreModules.World.Land
public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
{
m_scene = scene;
+ m_landBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
+
LandData.OwnerID = owner_id;
if (is_group_owned)
LandData.GroupID = owner_id;
@@ -152,9 +154,9 @@ namespace OpenSim.Region.CoreModules.World.Land
/// Returns true if the piece of land contains the specified point
public bool ContainsPoint(int x, int y)
{
- if (x >= 0 && y >= 0 && x < Constants.RegionSize && y < Constants.RegionSize)
+ if (x >= 0 && y >= 0 && x < m_scene.RegionInfo.RegionSizeX && y < m_scene.RegionInfo.RegionSizeY)
{
- return (LandBitmap[x / 4, y / 4] == true);
+ return (LandBitmap[x / landUnit, y / landUnit] == true);
}
else
{
@@ -194,7 +196,7 @@ namespace OpenSim.Region.CoreModules.World.Land
else
{
// Normal Calculations
- int parcelMax = (int)(((float)LandData.Area / 65536.0f)
+ int parcelMax = (int)(((float)LandData.Area / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
* (float)m_scene.RegionInfo.ObjectCapacity
* (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
// 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
else
{
//Normal Calculations
- int simMax = (int)(((float)LandData.SimwideArea / 65536.0f)
+ int simMax = (int)(((float)LandData.SimwideArea / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
* (float)m_scene.RegionInfo.ObjectCapacity);
return simMax;
}
@@ -224,7 +226,12 @@ namespace OpenSim.Region.CoreModules.World.Land
public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
{
IEstateModule estateModule = m_scene.RequestModuleInterface();
- uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
+ // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
+ uint regionFlags = (uint)(RegionFlags.PublicAllowed
+ | RegionFlags.AllowDirectTeleport
+ | RegionFlags.AllowParcelChanges
+ | RegionFlags.AllowVoice );
+
if (estateModule != null)
regionFlags = estateModule.GetRegionFlags();
@@ -546,8 +553,8 @@ namespace OpenSim.Region.CoreModules.World.Land
try
{
over =
- m_scene.LandChannel.GetLandObject(Util.Clamp((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)),
- Util.Clamp((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1)));
+ m_scene.LandChannel.GetLandObject(Util.Clamp((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)),
+ Util.Clamp((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1)));
}
catch (Exception)
{
@@ -694,15 +701,15 @@ namespace OpenSim.Region.CoreModules.World.Land
///
private void UpdateAABBAndAreaValues()
{
- int min_x = 64;
- int min_y = 64;
+ int min_x = 10000;
+ int min_y = 10000;
int max_x = 0;
int max_y = 0;
int tempArea = 0;
int x, y;
- for (x = 0; x < 64; x++)
+ for (x = 0; x < LandBitmap.GetLength(0); x++)
{
- for (y = 0; y < 64; y++)
+ for (y = 0; y < LandBitmap.GetLength(1); y++)
{
if (LandBitmap[x, y] == true)
{
@@ -710,31 +717,31 @@ namespace OpenSim.Region.CoreModules.World.Land
if (min_y > y) min_y = y;
if (max_x < x) max_x = x;
if (max_y < y) max_y = y;
- tempArea += 16; //16sqm peice of land
+ tempArea += landUnit * landUnit; //16sqm peice of land
}
}
}
- int tx = min_x * 4;
- if (tx > ((int)Constants.RegionSize - 1))
- tx = ((int)Constants.RegionSize - 1);
- int ty = min_y * 4;
- if (ty > ((int)Constants.RegionSize - 1))
- ty = ((int)Constants.RegionSize - 1);
+ int tx = min_x * landUnit;
+ if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
+ tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
+ int ty = min_y * landUnit;
+ if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
+ ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
LandData.AABBMin =
new Vector3(
- (float)(min_x * 4), (float)(min_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
+ (float)(min_x * landUnit), (float)(min_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
- tx = max_x * 4;
- if (tx > ((int)Constants.RegionSize - 1))
- tx = ((int)Constants.RegionSize - 1);
- ty = max_y * 4;
- if (ty > ((int)Constants.RegionSize - 1))
- ty = ((int)Constants.RegionSize - 1);
+ tx = max_x * landUnit;
+ if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
+ tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
+ ty = max_y * landUnit;
+ if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
+ ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
LandData.AABBMax
= new Vector3(
- (float)(max_x * 4), (float)(max_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
+ (float)(max_x * landUnit), (float)(max_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
LandData.Area = tempArea;
}
@@ -746,20 +753,11 @@ namespace OpenSim.Region.CoreModules.World.Land
///
/// Sets the land's bitmap manually
///
- /// 64x64 block representing where this land is on a map
+ /// block representing where this land is on a map mapped in a 4x4 meter grid
public void SetLandBitmap(bool[,] bitmap)
{
- if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
- {
- //Throw an exception - The bitmap is not 64x64
- //throw new Exception("Error: Invalid Parcel Bitmap");
- }
- else
- {
- //Valid: Lets set it
- LandBitmap = bitmap;
- ForceUpdateLandInfo();
- }
+ LandBitmap = bitmap;
+ ForceUpdateLandInfo();
}
///
@@ -773,12 +771,12 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool[,] BasicFullRegionLandBitmap()
{
- return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize);
+ return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY);
}
public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
{
- bool[,] tempBitmap = new bool[64,64];
+ bool[,] tempBitmap = new bool[(end_x-start_x)/landUnit,(end_y-start_y)/landUnit];
tempBitmap.Initialize();
tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
@@ -798,19 +796,13 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
bool set_value)
{
- if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
- {
- //Throw an exception - The bitmap is not 64x64
- //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
- }
-
int x, y;
- for (y = 0; y < 64; y++)
+ for (y = 0; y < land_bitmap.GetLength(1); y++)
{
- for (x = 0; x < 64; x++)
+ for (x = 0; x < land_bitmap.GetLength(0); x++)
{
- if (x >= start_x / 4 && x < end_x / 4
- && y >= start_y / 4 && y < end_y / 4)
+ if (x >= start_x / landUnit && x < end_x / landUnit
+ && y >= start_y / landUnit && y < end_y / landUnit)
{
land_bitmap[x, y] = set_value;
}
@@ -827,21 +819,21 @@ namespace OpenSim.Region.CoreModules.World.Land
///
public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
{
- if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
+ if (bitmap_base.GetLength(0) != bitmap_add.GetLength(0)
+ || bitmap_base.GetLength(1) != bitmap_add.GetLength(1)
+ || bitmap_add.Rank != 2
+ || bitmap_base.Rank != 2)
{
- //Throw an exception - The bitmap is not 64x64
- throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
- }
- if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
- {
- //Throw an exception - The bitmap is not 64x64
- throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
+ throw new Exception(
+ String.Format("{0} MergeLandBitmaps. merging maps not same size. baseSizeXY=<{1},{2}>, addSizeXY=<{3},{4}>",
+ LogHeader, bitmap_base.GetLength(0), bitmap_base.GetLength(1), bitmap_add.GetLength(0), bitmap_add.GetLength(1))
+ );
}
int x, y;
- for (y = 0; y < 64; y++)
+ for (y = 0; y < bitmap_base.GetLength(1); y++)
{
- for (x = 0; x < 64; x++)
+ for (x = 0; x < bitmap_add.GetLength(0); x++)
{
if (bitmap_add[x, y])
{
@@ -858,13 +850,13 @@ namespace OpenSim.Region.CoreModules.World.Land
///
private byte[] ConvertLandBitmapToBytes()
{
- byte[] tempConvertArr = new byte[512];
+ byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
byte tempByte = 0;
- int x, y, i, byteNum = 0;
- i = 0;
- for (y = 0; y < 64; y++)
+ int byteNum = 0;
+ int i = 0;
+ for (int y = 0; y < LandBitmap.GetLength(1); y++)
{
- for (x = 0; x < 64; x++)
+ for (int x = 0; x < LandBitmap.GetLength(0); x++)
{
tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
if (i % 8 == 0)
@@ -881,25 +873,45 @@ namespace OpenSim.Region.CoreModules.World.Land
private bool[,] ConvertBytesToLandBitmap()
{
- bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax];
+ bool[,] tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
tempConvertMap.Initialize();
byte tempByte = 0;
- int x = 0, y = 0, i = 0, bitNum = 0;
- for (i = 0; i < 512; i++)
+ // Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
+ int bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8);
+ int xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit);
+
+ if (bitmapLen == 512)
+ {
+ // Legacy bitmap being passed in. Use the legacy region size
+ // and only set the lower area of the larger region.
+ xLen = (int)(Constants.RegionSize / landUnit);
+ }
+ m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen);
+
+ int x = 0, y = 0;
+ for (int i = 0; i < bitmapLen; i++)
{
tempByte = LandData.Bitmap[i];
- for (bitNum = 0; bitNum < 8; bitNum++)
+ for (int bitNum = 0; bitNum < 8; bitNum++)
{
bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
- tempConvertMap[x, y] = bit;
+ try
+ {
+ tempConvertMap[x, y] = bit;
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("{0} ConvertBytestoLandBitmap: i={1}, x={2}, y={3}", LogHeader, i, x, y);
+ }
x++;
- if (x > 63)
+ if (x >= xLen)
{
x = 0;
y++;
}
}
}
+
return tempConvertMap;
}