aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs497
-rw-r--r--OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs8
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs9
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs6
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs3
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs318
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs187
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs63
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs2
16 files changed, 560 insertions, 563 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 27ace68..10122e6 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -189,8 +189,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
189 string message = c.Message; 189 string message = c.Message;
190 Scene scene = (Scene)c.Scene; 190 Scene scene = (Scene)c.Scene;
191 Vector3 fromPos = c.Position; 191 Vector3 fromPos = c.Position;
192 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, 192 Vector3 regionPos = new Vector3(scene.RegionInfo.WorldLocX, scene.RegionInfo.WorldLocY, 0);
193 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
194 193
195 if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel; 194 if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel;
196 195
@@ -342,8 +341,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
342 { 341 {
343 Vector3 fromRegionPos = fromPos + regionPos; 342 Vector3 fromRegionPos = fromPos + regionPos;
344 Vector3 toRegionPos = presence.AbsolutePosition + 343 Vector3 toRegionPos = presence.AbsolutePosition +
345 new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, 344 new Vector3(presence.Scene.RegionInfo.WorldLocX, presence.Scene.RegionInfo.WorldLocY, 0);
346 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
347 345
348 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); 346 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
349 347
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
index bfa30e6..7e50cc6 100644
--- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
@@ -667,8 +667,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
667 667
668 Vector3 avaPos = p.AbsolutePosition; 668 Vector3 avaPos = p.AbsolutePosition;
669 // Getting the global position for the Avatar 669 // Getting the global position for the Avatar
670 Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.RegionLocX*Constants.RegionSize + avaPos.X, 670 Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.WorldLocX + avaPos.X,
671 remoteClient.Scene.RegionInfo.RegionLocY*Constants.RegionSize + avaPos.Y, 671 remoteClient.Scene.RegionInfo.WorldLocY + avaPos.Y,
672 avaPos.Z); 672 avaPos.Z);
673 673
674 string landOwnerName = string.Empty; 674 string landOwnerName = string.Empty;
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 6545a99..13cc99a 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -269,9 +269,7 @@ namespace OpenSim.Region.CoreModules.Framework
269 foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID]) 269 foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID])
270 { 270 {
271 uint x, y; 271 uint x, y;
272 Utils.LongToUInts(kvp.Key, out x, out y); 272 Util.RegionHandleToRegionLoc(kvp.Key, out x, out y);
273 x = x / Constants.RegionSize;
274 y = y / Constants.RegionSize;
275 m_log.Info(" >> "+x+", "+y+": "+kvp.Value); 273 m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
276 } 274 }
277 } 275 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index ef5239a..4954cd9 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule 52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]";
55 56
56 public const int DefaultMaxTransferDistance = 4095; 57 public const int DefaultMaxTransferDistance = 4095;
57 public const bool WaitForAgentArrivedAtDestinationDefault = true; 58 public const bool WaitForAgentArrivedAtDestinationDefault = true;
@@ -433,10 +434,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
433 float posZLimit = 22; 434 float posZLimit = 22;
434 435
435 // TODO: Check other Scene HeightField 436 // TODO: Check other Scene HeightField
436 if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) 437 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
437 {
438 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
439 }
440 438
441 float newPosZ = posZLimit + localAVHeight; 439 float newPosZ = posZLimit + localAVHeight;
442 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 440 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
@@ -489,9 +487,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
489 487
490 if (finalDestination == null) 488 if (finalDestination == null)
491 { 489 {
492 m_log.WarnFormat( 490 m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}",
493 "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", 491 LogHeader, sp.Name, sp.UUID);
494 sp.Name, sp.UUID);
495 492
496 sp.ControllingClient.SendTeleportFailed("Problem at destination"); 493 sp.ControllingClient.SendTeleportFailed("Problem at destination");
497 return; 494 return;
@@ -532,11 +529,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
532 529
533 // and set the map-tile to '(Offline)' 530 // and set the map-tile to '(Offline)'
534 uint regX, regY; 531 uint regX, regY;
535 Utils.LongToUInts(regionHandle, out regX, out regY); 532 Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY);
536 533
537 MapBlockData block = new MapBlockData(); 534 MapBlockData block = new MapBlockData();
538 block.X = (ushort)(regX / Constants.RegionSize); 535 block.X = (ushort)Util.WorldToRegionLoc(regX);
539 block.Y = (ushort)(regY / Constants.RegionSize); 536 block.Y = (ushort)Util.WorldToRegionLoc(regY);
540 block.Access = 254; // == not there 537 block.Access = 254; // == not there
541 538
542 List<MapBlockData> blocks = new List<MapBlockData>(); 539 List<MapBlockData> blocks = new List<MapBlockData>();
@@ -1342,6 +1339,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1342 if (uinfo.HomeRegionID == UUID.Zero) 1339 if (uinfo.HomeRegionID == UUID.Zero)
1343 { 1340 {
1344 // can't find the Home region: Tell viewer and abort 1341 // can't find the Home region: Tell viewer and abort
1342 m_log.ErrorFormat("{0} No grid user info found for {1} {2}. Cannot send home.",
1343 LogHeader, client.Name, client.AgentId);
1345 client.SendTeleportFailed("You don't have a home position set."); 1344 client.SendTeleportFailed("You don't have a home position set.");
1346 return false; 1345 return false;
1347 } 1346 }
@@ -1375,7 +1374,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1375 1374
1376 #region Agent Crossings 1375 #region Agent Crossings
1377 1376
1378 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) 1377 // Given a position relative to the current region (which has previously been tested to
1378 // see that it is actually outside the current region), find the new region that the
1379 // point is actually in.
1380 // Returns the coordinates and information of the new region or 'null' of it doesn't exist.
1381 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos)
1379 { 1382 {
1380 version = String.Empty; 1383 version = String.Empty;
1381 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1384 newpos = new Vector3(pos.X, pos.Y, pos.Z);
@@ -1383,130 +1386,59 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1383// m_log.DebugFormat( 1386// m_log.DebugFormat(
1384// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1387// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1385 1388
1386 uint neighbourx = scene.RegionInfo.RegionLocX; 1389 // Compute world location of the object's position
1387 uint neighboury = scene.RegionInfo.RegionLocY; 1390 double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X;
1388 const float boundaryDistance = 1.7f; 1391 double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y;
1389 Vector3 northCross = new Vector3(0, boundaryDistance, 0); 1392
1390 Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0); 1393 // Call the grid service to lookup the region containing the new position.
1391 Vector3 eastCross = new Vector3(boundaryDistance, 0, 0); 1394 GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
1392 Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0); 1395 presenceWorldX, presenceWorldY);
1393 1396
1394 // distance into new region to place avatar 1397 if (neighbourRegion != null)
1395 const float enterDistance = 0.5f; 1398 {
1396 1399 // Compute the entity's position relative to the new region
1397 if (scene.TestBorderCross(pos + westCross, Cardinals.W)) 1400 newpos = new Vector3( (float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
1398 { 1401 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
1399 if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1402 pos.Z);
1400 { 1403
1401 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); 1404 // Check if banned from destination region.
1402 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); 1405 ExpiringCache<ulong, DateTime> r;
1406 DateTime banUntil;
1407 if (m_bannedRegions.TryGetValue(agentID, out r))
1408 {
1409 if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil))
1410 {
1411 if (DateTime.Now < banUntil)
1412 {
1413 // If we're banned from the destination, we just can't go there.
1414 neighbourRegion = null;
1415 }
1416 r.Remove(neighbourRegion.RegionHandle);
1417 }
1418 }
1419 else
1420 {
1421 r = null;
1403 } 1422 }
1404 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1405 {
1406 neighboury--;
1407 newpos.Y = Constants.RegionSize - enterDistance;
1408 }
1409
1410 neighbourx--;
1411 newpos.X = Constants.RegionSize - enterDistance;
1412 }
1413 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1414 {
1415 Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E);
1416 neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1417 newpos.X = enterDistance;
1418 1423
1419 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1424 // Check to see if we have access to the target region.
1425 string reason;
1426 if (neighbourRegion != null
1427 && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1420 { 1428 {
1421 neighboury--; 1429 if (r == null)
1422 newpos.Y = Constants.RegionSize - enterDistance; 1430 {
1423 } 1431 r = new ExpiringCache<ulong, DateTime>();
1424 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1432 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1425 {
1426 Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1427 neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
1428 newpos.Y = enterDistance;
1429 }
1430 }
1431 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1432 {
1433 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1434 neighboury--;
1435 newpos.Y = Constants.RegionSize - enterDistance;
1436 }
1437 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1438 {
1439 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1440 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1441 newpos.Y = enterDistance;
1442 }
1443
1444 /*
1445
1446 if (pos.X < boundaryDistance) //West
1447 {
1448 neighbourx--;
1449 newpos.X = Constants.RegionSize - enterDistance;
1450 }
1451 else if (pos.X > Constants.RegionSize - boundaryDistance) // East
1452 {
1453 neighbourx++;
1454 newpos.X = enterDistance;
1455 }
1456
1457 if (pos.Y < boundaryDistance) // South
1458 {
1459 neighboury--;
1460 newpos.Y = Constants.RegionSize - enterDistance;
1461 }
1462 else if (pos.Y > Constants.RegionSize - boundaryDistance) // North
1463 {
1464 neighboury++;
1465 newpos.Y = enterDistance;
1466 }
1467 */
1468
1469 xDest = neighbourx;
1470 yDest = neighboury;
1471
1472 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1473
1474 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1475
1476 ExpiringCache<ulong, DateTime> r;
1477 DateTime banUntil;
1478
1479 if (m_bannedRegions.TryGetValue(agentID, out r))
1480 {
1481 if (r.TryGetValue(neighbourHandle, out banUntil))
1482 {
1483 if (DateTime.Now < banUntil)
1484 return null;
1485 r.Remove(neighbourHandle);
1486 }
1487 }
1488 else
1489 {
1490 r = null;
1491 }
1492
1493 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1494
1495 string reason;
1496 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1497 {
1498 if (r == null)
1499 {
1500 r = new ExpiringCache<ulong, DateTime>();
1501 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1502 1433
1503 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); 1434 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1504 } 1435 }
1505 else 1436 else
1506 { 1437 {
1507 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1438 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1508 } 1439 }
1509 return null; 1440 neighbourRegion = null;
1441 }
1510 } 1442 }
1511 1443
1512 return neighbourRegion; 1444 return neighbourRegion;
@@ -1519,7 +1451,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1519 Vector3 newpos; 1451 Vector3 newpos;
1520 string version; 1452 string version;
1521 1453
1522 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos); 1454 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out version, out newpos);
1523 if (neighbourRegion == null) 1455 if (neighbourRegion == null)
1524 { 1456 {
1525 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); 1457 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
@@ -2028,15 +1960,80 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2028 } 1960 }
2029 } 1961 }
2030 1962
1963 // Computes the difference between two region bases.
1964 // Returns a vector of world coordinates (meters) from base of first region to the second.
1965 // The first region is the home region of the passed scene presence.
2031 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) 1966 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
2032 { 1967 {
2033 int rRegionX = (int)sp.Scene.RegionInfo.RegionLocX; 1968 /*
2034 int rRegionY = (int)sp.Scene.RegionInfo.RegionLocY; 1969 int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX;
1970 int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY;
2035 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize; 1971 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize;
2036 int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize; 1972 int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize;
2037 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize; 1973 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize;
2038 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize; 1974 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize;
2039 return new Vector3(shiftx, shifty, 0f); 1975 return new Vector3(shiftx, shifty, 0f);
1976 */
1977 return new Vector3(sp.Scene.RegionInfo.RegionLocX - neighbour.RegionLocX,
1978 sp.Scene.RegionInfo.RegionLocY - neighbour.RegionLocY,
1979 0f);
1980 }
1981
1982 // Given a world position (fractional meter coordinate), get the GridRegion info for
1983 // the region containing that point.
1984 // Return 'null' if no such region exists.
1985 private GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
1986 {
1987 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py);
1988 GridRegion ret = null;
1989
1990 // As an optimization, since most regions will be legacy sized regions (256x256), first try to get
1991 // the region at the appropriate legacy region location.
1992 uint possibleX = (uint)Math.Floor(px);
1993 possibleX -= possibleX % Constants.RegionSize;
1994 uint possibleY = (uint)Math.Floor(py);
1995 possibleY -= possibleY % Constants.RegionSize;
1996 ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY);
1997 if (ret != null)
1998 {
1999 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
2000 LogHeader, possibleX, possibleY, ret.RegionName);
2001 }
2002
2003 if (ret == null)
2004 {
2005 // If the simple lookup failed, search the larger area for a region that contains this point
2006 double range = (double)Constants.RegionSize * 2 + 2;
2007 while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
2008 {
2009 // Get from the grid service a list of regions that might contain this point
2010 List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID,
2011 (int)(px - range), (int)(px + range),
2012 (int)(py - range), (int)(py + range));
2013 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
2014 LogHeader, possibleRegions.Count, range);
2015 if (possibleRegions != null && possibleRegions.Count > 0)
2016 {
2017 // If we found some regions, check to see if the point is within
2018 foreach (GridRegion gr in possibleRegions)
2019 {
2020 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
2021 LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
2022 if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
2023 && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY))
2024 {
2025 // Found a region that contains the point
2026 ret = gr;
2027 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
2028 break;
2029 }
2030 }
2031 }
2032 // Larger search area for next time around if not found
2033 range *= 2;
2034 }
2035 }
2036 return ret;
2040 } 2037 }
2041 2038
2042 private void InformClientOfNeighbourCompleted(IAsyncResult iar) 2039 private void InformClientOfNeighbourCompleted(IAsyncResult iar)
@@ -2245,10 +2242,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2245 /// Move the given scene object into a new region depending on which region its absolute position has moved 2242 /// Move the given scene object into a new region depending on which region its absolute position has moved
2246 /// into. 2243 /// into.
2247 /// 2244 ///
2248 /// This method locates the new region handle and offsets the prim position for the new region 2245 /// Using the objects new world location, ask the grid service for a the new region and adjust the prim
2246 /// position to be relative to the new region.
2249 /// </summary> 2247 /// </summary>
2250 /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
2251 /// <param name="grp">the scene object that we're crossing</param> 2248 /// <param name="grp">the scene object that we're crossing</param>
2249 /// <param name="attemptedPosition">the attempted out of region position of the scene object. This position is
2250 /// relative to the region the object currently is in.</param>
2251 /// <param name="silent">if 'true', the deletion of the client from the region is not broadcast to the clients</param>
2252 public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent) 2252 public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
2253 { 2253 {
2254 if (grp == null) 2254 if (grp == null)
@@ -2274,208 +2274,51 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2274 return; 2274 return;
2275 } 2275 }
2276 2276
2277 int thisx = (int)scene.RegionInfo.RegionLocX; 2277 // Remember the old group position in case the region lookup fails so position can be restored.
2278 int thisy = (int)scene.RegionInfo.RegionLocY; 2278 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2279 Vector3 EastCross = new Vector3(0.1f, 0, 0);
2280 Vector3 WestCross = new Vector3(-0.1f, 0, 0);
2281 Vector3 NorthCross = new Vector3(0, 0.1f, 0);
2282 Vector3 SouthCross = new Vector3(0, -0.1f, 0);
2283
2284
2285 // use this if no borders were crossed!
2286 ulong newRegionHandle
2287 = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
2288 (uint)((thisy) * Constants.RegionSize));
2289
2290 Vector3 pos = attemptedPosition;
2291
2292 int changeX = 1;
2293 int changeY = 1;
2294
2295 if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
2296 {
2297 if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2298 {
2299
2300 Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2301
2302 if (crossedBorderx.BorderLine.Z > 0)
2303 {
2304 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2305 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2306 }
2307 else
2308 pos.X = ((pos.X + Constants.RegionSize));
2309
2310 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2311 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2312
2313 if (crossedBordery.BorderLine.Z > 0)
2314 {
2315 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2316 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2317 }
2318 else
2319 pos.Y = ((pos.Y + Constants.RegionSize));
2320
2321
2322
2323 newRegionHandle
2324 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
2325 (uint)((thisy - changeY) * Constants.RegionSize));
2326 // x - 1
2327 // y - 1
2328 }
2329 else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2330 {
2331 Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2332
2333 if (crossedBorderx.BorderLine.Z > 0)
2334 {
2335 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2336 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2337 }
2338 else
2339 pos.X = ((pos.X + Constants.RegionSize));
2340
2341
2342 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2343 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2344
2345 if (crossedBordery.BorderLine.Z > 0)
2346 {
2347 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2348 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2349 }
2350 else
2351 pos.Y = ((pos.Y + Constants.RegionSize));
2352 2279
2353 newRegionHandle 2280 // Compute the absolute position of the object.
2354 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), 2281 double objectWorldLocX = (double)scene.RegionInfo.WorldLocX + attemptedPosition.X;
2355 (uint)((thisy + changeY) * Constants.RegionSize)); 2282 double objectWorldLocY = (double)scene.RegionInfo.WorldLocY + attemptedPosition.Y;
2356 // x - 1
2357 // y + 1
2358 }
2359 else
2360 {
2361 Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2362 2283
2363 if (crossedBorderx.BorderLine.Z > 0) 2284 // Ask the grid service for the region that contains the passed address
2364 { 2285 GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, objectWorldLocX, objectWorldLocY);
2365 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2366 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2367 }
2368 else
2369 pos.X = ((pos.X + Constants.RegionSize));
2370 2286
2371 newRegionHandle 2287 Vector3 pos = Vector3.Zero;
2372 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), 2288 if (destination != null)
2373 (uint)(thisy * Constants.RegionSize));
2374 // x - 1
2375 }
2376 }
2377 else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
2378 { 2289 {
2379 if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) 2290 // Adjust the object's relative position from the old region (attemptedPosition)
2380 { 2291 // to be relative to the new region (pos).
2381 2292 pos = new Vector3( (float)(objectWorldLocX - (double)destination.RegionLocX),
2382 pos.X = ((pos.X - Constants.RegionSize)); 2293 (float)(objectWorldLocY - (double)destination.RegionLocY),
2383 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); 2294 attemptedPosition.Z);
2384 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2385
2386 if (crossedBordery.BorderLine.Z > 0)
2387 {
2388 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2389 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2390 }
2391 else
2392 pos.Y = ((pos.Y + Constants.RegionSize));
2393
2394
2395 newRegionHandle
2396 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2397 (uint)((thisy - changeY) * Constants.RegionSize));
2398 // x + 1
2399 // y - 1
2400 }
2401 else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2402 {
2403 pos.X = ((pos.X - Constants.RegionSize));
2404 pos.Y = ((pos.Y - Constants.RegionSize));
2405 newRegionHandle
2406 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2407 (uint)((thisy + changeY) * Constants.RegionSize));
2408 // x + 1
2409 // y + 1
2410 }
2411 else
2412 {
2413 pos.X = ((pos.X - Constants.RegionSize));
2414 newRegionHandle
2415 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2416 (uint)(thisy * Constants.RegionSize));
2417 // x + 1
2418 }
2419 } 2295 }
2420 else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2421 {
2422 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2423 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2424 2296
2425 if (crossedBordery.BorderLine.Z > 0) 2297 if (destination != null)
2298 {
2299 if (!CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2426 { 2300 {
2427 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); 2301 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);
2428 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); 2302
2303 // We are going to move the object back to the old position so long as the old position
2304 // is in the region
2305 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
2306 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
2307 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
2308
2309 grp.AbsolutePosition = oldGroupPosition;
2310 grp.Velocity = Vector3.Zero;
2311 if (grp.RootPart.PhysActor != null)
2312 grp.RootPart.PhysActor.CrossingFailure();
2313
2314 if (grp.RootPart.KeyframeMotion != null)
2315 grp.RootPart.KeyframeMotion.CrossingFailure();
2316
2317 grp.ScheduleGroupForFullUpdate();
2429 } 2318 }
2430 else
2431 pos.Y = ((pos.Y + Constants.RegionSize));
2432
2433 newRegionHandle
2434 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
2435 // y - 1
2436 } 2319 }
2437 else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2438 {
2439
2440 pos.Y = ((pos.Y - Constants.RegionSize));
2441 newRegionHandle
2442 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
2443 // y + 1
2444 }
2445
2446 // Offset the positions for the new region across the border
2447 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2448
2449 // If we fail to cross the border, then reset the position of the scene object on that border.
2450 uint x = 0, y = 0;
2451 Utils.LongToUInts(newRegionHandle, out x, out y);
2452 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2453
2454 if (destination != null)
2455 {
2456 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2457 return; // we did it
2458 }
2459
2460 // no one or failed lets go back and tell physics to go on
2461 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
2462 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
2463 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
2464
2465 grp.AbsolutePosition = oldGroupPosition;
2466 grp.Velocity = Vector3.Zero;
2467
2468 if (grp.RootPart.PhysActor != null)
2469 grp.RootPart.PhysActor.CrossingFailure();
2470
2471 if (grp.RootPart.KeyframeMotion != null)
2472 grp.RootPart.KeyframeMotion.CrossingFailure();
2473
2474 grp.ScheduleGroupForFullUpdate();
2475 } 2320 }
2476 2321
2477
2478
2479 /// <summary> 2322 /// <summary>
2480 /// Move the given scene object into a new region 2323 /// Move the given scene object into a new region
2481 /// </summary> 2324 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
index d943b20..4e7ad75 100644
--- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
@@ -213,8 +213,8 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
213 if (part != null) 213 if (part != null)
214 { 214 {
215 ObjectRegionName = s.RegionInfo.RegionName; 215 ObjectRegionName = s.RegionInfo.RegionName;
216 uint localX = (s.RegionInfo.RegionLocX * (int)Constants.RegionSize); 216 uint localX = s.RegionInfo.WorldLocX;
217 uint localY = (s.RegionInfo.RegionLocY * (int)Constants.RegionSize); 217 uint localY = s.RegionInfo.WorldLocY;
218 ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")"; 218 ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")";
219 return part; 219 return part;
220 } 220 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
index 31ef79b..277293a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
@@ -192,8 +192,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
192 return m_GridService.GetRegionByUUID(scopeID, regionID); 192 return m_GridService.GetRegionByUUID(scopeID, regionID);
193 } 193 }
194 194
195 // Get a region given its base coordinates.
196 // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
197 // be the base coordinate of the region.
195 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) 198 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
196 { 199 {
200 m_log.DebugFormat("{0} GetRegionByPosition. pos=<{1},{2}>", "[LOCAL GRID SERVICE CONNECTOR", x, y);
197 GridRegion region = null; 201 GridRegion region = null;
198 202
199 // First see if it's a neighbour, even if it isn't on this sim. 203 // First see if it's a neighbour, even if it isn't on this sim.
@@ -206,6 +210,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
206 region = rcache.GetRegionByPosition(x, y); 210 region = rcache.GetRegionByPosition(x, y);
207 if (region != null) 211 if (region != null)
208 { 212 {
213 m_log.DebugFormat("{0} GetRegionByPosition. Found region {1}. Pos=<{2},{3}>",
214 "[LOCAL GRID SERVICE CONNECTOR", region.RegionName, x, y);
209 return region; 215 return region;
210 } 216 }
211 } 217 }
@@ -268,7 +274,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
268 caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key); 274 caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key);
269 List<GridRegion> regions = kvp.Value.GetNeighbours(); 275 List<GridRegion> regions = kvp.Value.GetNeighbours();
270 foreach (GridRegion r in regions) 276 foreach (GridRegion r in regions)
271 caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize); 277 caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, Util.WorldToRegionLoc((uint)r.RegionLocX), Util.WorldToRegionLoc((uint)r.RegionLocY));
272 } 278 }
273 } 279 }
274 280
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs
index 9172536..33ff7ea 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
66 return; 66 return;
67 67
68 m_log.DebugFormat("[REGION CACHE]: (on region {0}) Region {1} is up @ {2}-{3}", 68 m_log.DebugFormat("[REGION CACHE]: (on region {0}) Region {1} is up @ {2}-{3}",
69 m_scene.RegionInfo.RegionName, otherRegion.RegionName, otherRegion.RegionLocX / Constants.RegionSize, otherRegion.RegionLocY / Constants.RegionSize); 69 m_scene.RegionInfo.RegionName, otherRegion.RegionName, Util.WorldToRegionLoc((uint)otherRegion.RegionLocX), Util.WorldToRegionLoc((uint)otherRegion.RegionLocY));
70 70
71 m_neighbours[otherRegion.RegionHandle] = otherRegion; 71 m_neighbours[otherRegion.RegionHandle] = otherRegion;
72 } 72 }
@@ -82,11 +82,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
82 return new List<GridRegion>(m_neighbours.Values); 82 return new List<GridRegion>(m_neighbours.Values);
83 } 83 }
84 84
85 // Get a region given its base coordinates.
86 // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
87 // be the base coordinate of the region.
88 // The snapping is technically unnecessary but is harmless because regions are always
89 // multiples of the legacy region size (256).
85 public GridRegion GetRegionByPosition(int x, int y) 90 public GridRegion GetRegionByPosition(int x, int y)
86 { 91 {
87 uint xsnap = (uint)(x / Constants.RegionSize) * Constants.RegionSize; 92 uint xsnap = (uint)(x / Constants.RegionSize) * Constants.RegionSize;
88 uint ysnap = (uint)(y / Constants.RegionSize) * Constants.RegionSize; 93 uint ysnap = (uint)(y / Constants.RegionSize) * Constants.RegionSize;
89 ulong handle = Utils.UIntsToLong(xsnap, ysnap); 94 ulong handle = Util.RegionWorldLocToHandle(xsnap, ysnap);
90 95
91 if (m_neighbours.ContainsKey(handle)) 96 if (m_neighbours.ContainsKey(handle))
92 return m_neighbours[handle]; 97 return m_neighbours[handle];
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
index 6a57d1f..ac81337 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
@@ -186,10 +186,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
186 return rinfo; 186 return rinfo;
187 } 187 }
188 188
189 // Get a region given its base coordinates.
190 // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
191 // be the base coordinate of the region.
192 // The coordinates are world coords (meters), NOT region units.
189 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) 193 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
190 { 194 {
191 bool inCache = false; 195 bool inCache = false;
192 GridRegion rinfo = m_RegionInfoCache.Get(scopeID, Util.UIntsToLong((uint)x, (uint)y), out inCache); 196 GridRegion rinfo = m_RegionInfoCache.Get(scopeID, Util.RegionWorldLocToHandle((uint)x, (uint)y), out inCache);
193 if (inCache) 197 if (inCache)
194 return rinfo; 198 return rinfo;
195 199
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
index 4338133..25ae689 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
@@ -34,6 +34,7 @@ using log4net.Config;
34using Nini.Config; 34using Nini.Config;
35using NUnit.Framework; 35using NUnit.Framework;
36using OpenMetaverse; 36using OpenMetaverse;
37
37using OpenSim.Framework; 38using OpenSim.Framework;
38using OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid; 39using OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid;
39using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
@@ -141,7 +142,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
141 Assert.IsNotNull(result, "Retrieved GetRegionByUUID is null"); 142 Assert.IsNotNull(result, "Retrieved GetRegionByUUID is null");
142 Assert.That(result.RegionID, Is.EqualTo(new UUID(1)), "Retrieved region's UUID does not match"); 143 Assert.That(result.RegionID, Is.EqualTo(new UUID(1)), "Retrieved region's UUID does not match");
143 144
144 result = m_LocalConnector.GetRegionByPosition(UUID.Zero, 1000 * (int)Constants.RegionSize, 1000 * (int)Constants.RegionSize); 145 result = m_LocalConnector.GetRegionByPosition(UUID.Zero, (int)Util.RegionToWorldLoc(1000), (int)Util.RegionToWorldLoc(1000));
145 Assert.IsNotNull(result, "Retrieved GetRegionByPosition is null"); 146 Assert.IsNotNull(result, "Retrieved GetRegionByPosition is null");
146 Assert.That(result.RegionLocX, Is.EqualTo(1000 * (int)Constants.RegionSize), "Retrieved region's position does not match"); 147 Assert.That(result.RegionLocX, Is.EqualTo(1000 * (int)Constants.RegionSize), "Retrieved region's position does not match");
147 148
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 73c4d6c..99db7ff 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -64,6 +64,7 @@ namespace OpenSim.Region.CoreModules.World.Land
64 public class LandManagementModule : INonSharedRegionModule 64 public class LandManagementModule : INonSharedRegionModule
65 { 65 {
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 68
68 private static readonly string remoteParcelRequestPath = "0009/"; 69 private static readonly string remoteParcelRequestPath = "0009/";
69 70
@@ -74,15 +75,11 @@ namespace OpenSim.Region.CoreModules.World.Land
74 protected IPrimCountModule m_primCountModule; 75 protected IPrimCountModule m_primCountModule;
75 protected IDialogModule m_Dialog; 76 protected IDialogModule m_Dialog;
76 77
77 // Minimum for parcels to work is 64m even if we don't actually use them.
78 #pragma warning disable 0429
79 private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
80 #pragma warning restore 0429
81
82 /// <value> 78 /// <value>
83 /// Local land ids at specified region co-ordinates (region size / 4) 79 /// Local land ids at specified region co-ordinates (region size / 4)
84 /// </value> 80 /// </value>
85 private readonly int[,] m_landIDList = new int[landArrayMax, landArrayMax]; 81 private int[,] m_landIDList;
82 private const int landUnit = 4;
86 83
87 /// <value> 84 /// <value>
88 /// Land objects keyed by local id 85 /// Land objects keyed by local id
@@ -115,6 +112,8 @@ namespace OpenSim.Region.CoreModules.World.Land
115 public void AddRegion(Scene scene) 112 public void AddRegion(Scene scene)
116 { 113 {
117 m_scene = scene; 114 m_scene = scene;
115 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
116
118 m_landIDList.Initialize(); 117 m_landIDList.Initialize();
119 landChannel = new LandChannel(scene, this); 118 landChannel = new LandChannel(scene, this);
120 119
@@ -297,6 +296,7 @@ namespace OpenSim.Region.CoreModules.World.Land
297 { 296 {
298 m_landList.Clear(); 297 m_landList.Clear();
299 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 298 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
299 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
300 m_landIDList.Initialize(); 300 m_landIDList.Initialize();
301 } 301 }
302 } 302 }
@@ -311,7 +311,8 @@ namespace OpenSim.Region.CoreModules.World.Land
311 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 311 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
312 312
313 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 313 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
314 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 314 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
315 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
315 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 316 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
316 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 317 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
317 318
@@ -438,8 +439,8 @@ namespace OpenSim.Region.CoreModules.World.Land
438 439
439 public void SendLandUpdate(ScenePresence avatar, bool force) 440 public void SendLandUpdate(ScenePresence avatar, bool force)
440 { 441 {
441 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 442 ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
442 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 443 (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
443 444
444 if (over != null) 445 if (over != null)
445 { 446 {
@@ -605,17 +606,29 @@ namespace OpenSim.Region.CoreModules.World.Land
605 new_land.LandData.LocalID = newLandLocalID; 606 new_land.LandData.LocalID = newLandLocalID;
606 607
607 bool[,] landBitmap = new_land.GetLandBitmap(); 608 bool[,] landBitmap = new_land.GetLandBitmap();
608 for (int x = 0; x < landArrayMax; x++) 609 // m_log.DebugFormat("{0} AddLandObject. new_land.bitmapSize=({1},{2}). newLocalID={3}",
610 // LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), newLandLocalID);
611
612 if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
609 { 613 {
610 for (int y = 0; y < landArrayMax; y++) 614 // Going to variable sized regions can cause mismatches
615 m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})",
616 LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1) );
617 }
618 else
619 {
620 for (int x = 0; x < landBitmap.GetLength(0); x++)
611 { 621 {
612 if (landBitmap[x, y]) 622 for (int y = 0; y < landBitmap.GetLength(1); y++)
613 { 623 {
614// m_log.DebugFormat( 624 if (landBitmap[x, y])
615// "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", 625 {
616// new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName); 626 // m_log.DebugFormat(
617 627 // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
618 m_landIDList[x, y] = newLandLocalID; 628 // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
629
630 m_landIDList[x, y] = newLandLocalID;
631 }
619 } 632 }
620 } 633 }
621 } 634 }
@@ -637,9 +650,9 @@ namespace OpenSim.Region.CoreModules.World.Land
637 ILandObject land; 650 ILandObject land;
638 lock (m_landList) 651 lock (m_landList)
639 { 652 {
640 for (int x = 0; x < 64; x++) 653 for (int x = 0; x < m_landIDList.GetLength(0); x++)
641 { 654 {
642 for (int y = 0; y < 64; y++) 655 for (int y = 0; y < m_landIDList.GetLength(1); y++)
643 { 656 {
644 if (m_landIDList[x, y] == local_id) 657 if (m_landIDList[x, y] == local_id)
645 { 658 {
@@ -691,9 +704,9 @@ namespace OpenSim.Region.CoreModules.World.Land
691 bool[,] landBitmapSlave = slave.GetLandBitmap(); 704 bool[,] landBitmapSlave = slave.GetLandBitmap();
692 lock (m_landList) 705 lock (m_landList)
693 { 706 {
694 for (int x = 0; x < 64; x++) 707 for (int x = 0; x < landBitmapSlave.GetLength(0); x++)
695 { 708 {
696 for (int y = 0; y < 64; y++) 709 for (int y = 0; y < landBitmapSlave.GetLength(1); y++)
697 { 710 {
698 if (landBitmapSlave[x, y]) 711 if (landBitmapSlave[x, y])
699 { 712 {
@@ -727,23 +740,28 @@ namespace OpenSim.Region.CoreModules.World.Land
727 /// <returns>Land object at the point supplied</returns> 740 /// <returns>Land object at the point supplied</returns>
728 public ILandObject GetLandObject(float x_float, float y_float) 741 public ILandObject GetLandObject(float x_float, float y_float)
729 { 742 {
743 return GetLandObject((int)x_float, (int)y_float, true /* returnNullIfLandObjectNotFound */);
744 /*
730 int x; 745 int x;
731 int y; 746 int y;
732 747
733 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 748 if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0)
734 return null; 749 return null;
735 750
736 try 751 try
737 { 752 {
738 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0)); 753 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit));
739 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / 4.0)); 754 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit));
740 } 755 }
741 catch (OverflowException) 756 catch (OverflowException)
742 { 757 {
743 return null; 758 return null;
744 } 759 }
745 760
746 if (x >= 64 || y >= 64 || x < 0 || y < 0) 761 if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit)
762 || y >= (m_scene.RegionInfo.RegionSizeY / landUnit)
763 || x < 0
764 || y < 0)
747 { 765 {
748 return null; 766 return null;
749 } 767 }
@@ -759,38 +777,122 @@ namespace OpenSim.Region.CoreModules.World.Land
759// m_log.DebugFormat( 777// m_log.DebugFormat(
760// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}", 778// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
761// x, y, m_scene.RegionInfo.RegionName); 779// x, y, m_scene.RegionInfo.RegionName);
762 780
763 if (m_landList.ContainsKey(m_landIDList[x, y])) 781 try
764 return m_landList[m_landIDList[x, y]]; 782 {
783 if (m_landList.ContainsKey(m_landIDList[x, y]))
784 return m_landList[m_landIDList[x, y]];
785 }
786 catch (Exception e)
787 {
788 m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})",
789 LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
790 }
765 791
766 return null; 792 return null;
767 } 793 }
794 */
768 } 795 }
769 796
797 // Public entry.
798 // Throws exception if land object is not found
770 public ILandObject GetLandObject(int x, int y) 799 public ILandObject GetLandObject(int x, int y)
771 { 800 {
772 if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0) 801 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */);
802 }
803
804 // Given a region position, return the parcel land object for that location
805 private ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectNotFound)
806 {
807 ILandObject ret = null;
808
809 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
773 { 810 {
774 // These exceptions here will cause a lot of complaints from the users specifically because 811 // These exceptions here will cause a lot of complaints from the users specifically because
775 // they happen every time at border crossings 812 // they happen every time at border crossings
776 throw new Exception("Error: Parcel not found at point " + x + ", " + y); 813 if (returnNullIfLandObjectNotFound)
814 return null;
815 else
816 throw new Exception(
817 String.Format("{0} GetLandObject for non-existant position. Region={1}, pos=<{2},{3}",
818 LogHeader, m_scene.RegionInfo.RegionName, x, y)
819 );
777 } 820 }
778 821
779 lock (m_landIDList) 822 lock (m_landIDList)
780 { 823 {
781 try 824 try
782 { 825 {
783 return m_landList[m_landIDList[x / 4, y / 4]]; 826 int landID = m_landIDList[x / landUnit, y / landUnit];
827 if (landID == 0)
828 {
829 // Zero is the uninitialized value saying there is no parcel for this location.
830 // This sometimes happens when terrain is resized.
831 if (m_landList.Count == 1)
832 {
833 int onlyParcelID = 0;
834 ILandObject onlyLandObject = null;
835 foreach (KeyValuePair<int, ILandObject> kvp in m_landList)
836 {
837 onlyParcelID = kvp.Key;
838 onlyLandObject = kvp.Value;
839 break;
840 }
841
842 // There is only one parcel. Grow it to fill all the unallocated spaces.
843 for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
844 for (int yy = 0; yy < m_landIDList.GetLength(1); yy++)
845 if (m_landIDList[xx, yy] == 0)
846 m_landIDList[xx, yy] = onlyParcelID;
847
848 onlyLandObject.LandBitmap = CreateBitmapForID(onlyParcelID);
849 landID = onlyParcelID;
850 }
851 else
852 {
853 // There are several other parcels so we must create a new one for the unassigned space
854 ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
855 // Claim all the unclaimed "0" ids
856 newLand.SetLandBitmap(CreateBitmapForID(0));
857 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
858 newLand.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
859 AddLandObject(newLand);
860 landID = m_lastLandLocalID;
861 }
862 }
863
864 ret = m_landList[landID];
784 } 865 }
785 catch (IndexOutOfRangeException) 866 catch (IndexOutOfRangeException)
786 { 867 {
787// m_log.WarnFormat( 868 m_log.ErrorFormat(
788// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}", 869 "{0} GetLandObject: Tried to retrieve land object from out of bounds co-ordinate ({1},{2}) in {3}. landListSize=({4},{5})",
789// x, y, m_scene.RegionInfo.RegionName); 870 LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
790 871 return null;
872 }
873 catch
874 {
875 m_log.ErrorFormat(
876 "{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]);
791 return null; 878 return null;
792 } 879 }
793 } 880 }
881 return ret;
882 }
883
884 // Create a 'parcel is here' bitmap for the parcel identified by the passed landID
885 private bool[,] CreateBitmapForID(int landID)
886 {
887 bool[,] ret = new bool[m_landIDList.GetLength(0), m_landIDList.GetLength(1)];
888 ret.Initialize();
889
890 for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
891 for (int yy = 0; yy < m_landIDList.GetLength(0); yy++)
892 if (m_landIDList[xx, yy] == landID)
893 ret[xx, yy] = true;
894
895 return ret;
794 } 896 }
795 897
796 #endregion 898 #endregion
@@ -1053,85 +1155,93 @@ namespace OpenSim.Region.CoreModules.World.Land
1053 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1155 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1054 int byteArrayCount = 0; 1156 int byteArrayCount = 0;
1055 int sequenceID = 0; 1157 int sequenceID = 0;
1056 int blockmeters = 4 * (int) Constants.RegionSize/(int)Constants.TerrainPatchSize;
1057
1058 1158
1059 for (int y = 0; y < blockmeters; y++) 1159 // Layer data is in landUnit (4m) chunks
1160 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); y++)
1060 { 1161 {
1061 for (int x = 0; x < blockmeters; x++) 1162 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); x++)
1062 { 1163 {
1063 byte tempByte = 0; //This represents the byte for the current 4x4 1164 byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * landUnit, y * landUnit), x, y, remote_client);
1165 byteArrayCount++;
1166 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
1167 {
1168 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1169 byteArrayCount = 0;
1170 sequenceID++;
1171 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1172 }
1064 1173
1065 ILandObject currentParcelBlock = GetLandObject(x * 4, y * 4); 1174 }
1175 }
1176 if (byteArrayCount != 0)
1177 {
1178 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1179 }
1180 }
1066 1181
1067 if (currentParcelBlock != null) 1182 private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client)
1068 { 1183 {
1069 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) 1184 byte tempByte = 0; //This represents the byte for the current 4x4
1070 {
1071 //Owner Flag
1072 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1073 }
1074 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1075 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1076 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1077 {
1078 //Sale Flag
1079 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
1080 }
1081 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1082 {
1083 //Public Flag
1084 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
1085 }
1086 else
1087 {
1088 //Other Flag
1089 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
1090 }
1091 1185
1092 //Now for border control 1186 if (currentParcelBlock != null)
1187 {
1188 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
1189 {
1190 //Owner Flag
1191 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1192 }
1193 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1194 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1195 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1196 {
1197 //Sale Flag
1198 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
1199 }
1200 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1201 {
1202 //Public Flag
1203 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
1204 }
1205 else
1206 {
1207 //Other Flag
1208 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
1209 }
1093 1210
1094 ILandObject westParcel = null; 1211 //Now for border control
1095 ILandObject southParcel = null;
1096 if (x > 0)
1097 {
1098 westParcel = GetLandObject((x - 1) * 4, y * 4);
1099 }
1100 if (y > 0)
1101 {
1102 southParcel = GetLandObject(x * 4, (y - 1) * 4);
1103 }
1104 1212
1105 if (x == 0) 1213 ILandObject westParcel = null;
1106 { 1214 ILandObject southParcel = null;
1107 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); 1215 if (x > 0)
1108 } 1216 {
1109 else if (westParcel != null && westParcel != currentParcelBlock) 1217 westParcel = GetLandObject((x - 1) * landUnit, y * landUnit);
1110 { 1218 }
1111 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); 1219 if (y > 0)
1112 } 1220 {
1221 southParcel = GetLandObject(x * landUnit, (y - 1) * landUnit);
1222 }
1113 1223
1114 if (y == 0) 1224 if (x == 0)
1115 { 1225 {
1116 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1226 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1117 } 1227 }
1118 else if (southParcel != null && southParcel != currentParcelBlock) 1228 else if (westParcel != null && westParcel != currentParcelBlock)
1119 { 1229 {
1120 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1230 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1121 } 1231 }
1122 1232
1123 byteArray[byteArrayCount] = tempByte; 1233 if (y == 0)
1124 byteArrayCount++; 1234 {
1125 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) 1235 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
1126 { 1236 }
1127 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1237 else if (southParcel != null && southParcel != currentParcelBlock)
1128 byteArrayCount = 0; 1238 {
1129 sequenceID++; 1239 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
1130 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1131 }
1132 }
1133 } 1240 }
1241
1134 } 1242 }
1243
1244 return tempByte;
1135 } 1245 }
1136 1246
1137 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, 1247 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
@@ -1679,7 +1789,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1679 { 1789 {
1680 // most likely still cached from building the extLandData entry 1790 // most likely still cached from building the extLandData entry
1681 uint x = 0, y = 0; 1791 uint x = 0, y = 0;
1682 Utils.LongToUInts(data.RegionHandle, out x, out y); 1792 Util.RegionHandleToWorldLoc(data.RegionHandle, out x, out y);
1683 info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); 1793 info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y);
1684 } 1794 }
1685 // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark. 1795 // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark.
@@ -2007,4 +2117,4 @@ namespace OpenSim.Region.CoreModules.World.Land
2007 cdl.AddToStringBuilder(report); 2117 cdl.AddToStringBuilder(report);
2008 } 2118 }
2009 } 2119 }
2010} \ No newline at end of file 2120}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index e54c849..f8f4986 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,15 +93,17 @@ 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
105 m_log.ErrorFormat("{0} StartPoint. No start point found. bitmapSize=<{1},{2}>",
106 LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
105 return new Vector3(-1, -1, -1); 107 return new Vector3(-1, -1, -1);
106 } 108 }
107 } 109 }
@@ -110,17 +112,19 @@ namespace OpenSim.Region.CoreModules.World.Land
110 { 112 {
111 get 113 get
112 { 114 {
113 for (int y = landArrayMax - 1; y >= 0; y--) 115 for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--)
114 { 116 {
115 for (int x = landArrayMax - 1; x >= 0; x--) 117 for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--)
116 { 118 {
117 if (LandBitmap[x, y]) 119 if (LandBitmap[x, y])
118 { 120 {
119 return new Vector3(x * 4 + 4, y * 4 + 4, 0); 121 return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0);
120 } 122 }
121 } 123 }
122 } 124 }
123 125
126 m_log.ErrorFormat("{0} EndPoint. No end point found. bitmapSize=<{1},{2}>",
127 LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
124 return new Vector3(-1, -1, -1); 128 return new Vector3(-1, -1, -1);
125 } 129 }
126 } 130 }
@@ -130,6 +134,8 @@ namespace OpenSim.Region.CoreModules.World.Land
130 public LandObject(UUID owner_id, bool is_group_owned, Scene scene) 134 public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
131 { 135 {
132 m_scene = scene; 136 m_scene = scene;
137 m_landBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
138
133 LandData.OwnerID = owner_id; 139 LandData.OwnerID = owner_id;
134 if (is_group_owned) 140 if (is_group_owned)
135 LandData.GroupID = owner_id; 141 LandData.GroupID = owner_id;
@@ -152,9 +158,9 @@ namespace OpenSim.Region.CoreModules.World.Land
152 /// <returns>Returns true if the piece of land contains the specified point</returns> 158 /// <returns>Returns true if the piece of land contains the specified point</returns>
153 public bool ContainsPoint(int x, int y) 159 public bool ContainsPoint(int x, int y)
154 { 160 {
155 if (x >= 0 && y >= 0 && x < Constants.RegionSize && y < Constants.RegionSize) 161 if (x >= 0 && y >= 0 && x < m_scene.RegionInfo.RegionSizeX && y < m_scene.RegionInfo.RegionSizeY)
156 { 162 {
157 return (LandBitmap[x / 4, y / 4] == true); 163 return (LandBitmap[x / landUnit, y / landUnit] == true);
158 } 164 }
159 else 165 else
160 { 166 {
@@ -194,7 +200,7 @@ namespace OpenSim.Region.CoreModules.World.Land
194 else 200 else
195 { 201 {
196 // Normal Calculations 202 // Normal Calculations
197 int parcelMax = (int)(((float)LandData.Area / 65536.0f) 203 int parcelMax = (int)(((float)LandData.Area / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
198 * (float)m_scene.RegionInfo.ObjectCapacity 204 * (float)m_scene.RegionInfo.ObjectCapacity
199 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 205 * (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! 206 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL!
@@ -211,7 +217,7 @@ namespace OpenSim.Region.CoreModules.World.Land
211 else 217 else
212 { 218 {
213 //Normal Calculations 219 //Normal Calculations
214 int simMax = (int)(((float)LandData.SimwideArea / 65536.0f) 220 int simMax = (int)(((float)LandData.SimwideArea / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
215 * (float)m_scene.RegionInfo.ObjectCapacity); 221 * (float)m_scene.RegionInfo.ObjectCapacity);
216 return simMax; 222 return simMax;
217 } 223 }
@@ -224,7 +230,12 @@ namespace OpenSim.Region.CoreModules.World.Land
224 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) 230 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
225 { 231 {
226 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 232 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
227 uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); 233 // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
234 uint regionFlags = (uint)(RegionFlags.PublicAllowed
235 | RegionFlags.AllowDirectTeleport
236 | RegionFlags.AllowParcelChanges
237 | RegionFlags.AllowVoice );
238
228 if (estateModule != null) 239 if (estateModule != null)
229 regionFlags = estateModule.GetRegionFlags(); 240 regionFlags = estateModule.GetRegionFlags();
230 241
@@ -559,8 +570,8 @@ namespace OpenSim.Region.CoreModules.World.Land
559 try 570 try
560 { 571 {
561 over = 572 over =
562 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), 573 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)),
563 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); 574 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1)));
564 } 575 }
565 catch (Exception) 576 catch (Exception)
566 { 577 {
@@ -707,15 +718,15 @@ namespace OpenSim.Region.CoreModules.World.Land
707 /// </summary> 718 /// </summary>
708 private void UpdateAABBAndAreaValues() 719 private void UpdateAABBAndAreaValues()
709 { 720 {
710 int min_x = 64; 721 int min_x = 10000;
711 int min_y = 64; 722 int min_y = 10000;
712 int max_x = 0; 723 int max_x = 0;
713 int max_y = 0; 724 int max_y = 0;
714 int tempArea = 0; 725 int tempArea = 0;
715 int x, y; 726 int x, y;
716 for (x = 0; x < 64; x++) 727 for (x = 0; x < LandBitmap.GetLength(0); x++)
717 { 728 {
718 for (y = 0; y < 64; y++) 729 for (y = 0; y < LandBitmap.GetLength(1); y++)
719 { 730 {
720 if (LandBitmap[x, y] == true) 731 if (LandBitmap[x, y] == true)
721 { 732 {
@@ -723,31 +734,31 @@ namespace OpenSim.Region.CoreModules.World.Land
723 if (min_y > y) min_y = y; 734 if (min_y > y) min_y = y;
724 if (max_x < x) max_x = x; 735 if (max_x < x) max_x = x;
725 if (max_y < y) max_y = y; 736 if (max_y < y) max_y = y;
726 tempArea += 16; //16sqm peice of land 737 tempArea += landUnit * landUnit; //16sqm peice of land
727 } 738 }
728 } 739 }
729 } 740 }
730 int tx = min_x * 4; 741 int tx = min_x * landUnit;
731 if (tx > ((int)Constants.RegionSize - 1)) 742 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
732 tx = ((int)Constants.RegionSize - 1); 743 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
733 int ty = min_y * 4; 744 int ty = min_y * landUnit;
734 if (ty > ((int)Constants.RegionSize - 1)) 745 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
735 ty = ((int)Constants.RegionSize - 1); 746 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
736 747
737 LandData.AABBMin = 748 LandData.AABBMin =
738 new Vector3( 749 new Vector3(
739 (float)(min_x * 4), (float)(min_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 750 (float)(min_x * landUnit), (float)(min_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
740 751
741 tx = max_x * 4; 752 tx = max_x * landUnit;
742 if (tx > ((int)Constants.RegionSize - 1)) 753 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
743 tx = ((int)Constants.RegionSize - 1); 754 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
744 ty = max_y * 4; 755 ty = max_y * landUnit;
745 if (ty > ((int)Constants.RegionSize - 1)) 756 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
746 ty = ((int)Constants.RegionSize - 1); 757 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
747 758
748 LandData.AABBMax 759 LandData.AABBMax
749 = new Vector3( 760 = new Vector3(
750 (float)(max_x * 4), (float)(max_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 761 (float)(max_x * landUnit), (float)(max_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
751 762
752 LandData.Area = tempArea; 763 LandData.Area = tempArea;
753 } 764 }
@@ -759,20 +770,12 @@ namespace OpenSim.Region.CoreModules.World.Land
759 /// <summary> 770 /// <summary>
760 /// Sets the land's bitmap manually 771 /// Sets the land's bitmap manually
761 /// </summary> 772 /// </summary>
762 /// <param name="bitmap">64x64 block representing where this land is on a map</param> 773 /// <param name="bitmap">block representing where this land is on a map mapped in a 4x4 meter grid</param>
763 public void SetLandBitmap(bool[,] bitmap) 774 public void SetLandBitmap(bool[,] bitmap)
764 { 775 {
765 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) 776 LandBitmap = bitmap;
766 { 777 // m_log.DebugFormat("{0} SetLandBitmap. BitmapSize=<{1},{2}>", LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
767 //Throw an exception - The bitmap is not 64x64 778 ForceUpdateLandInfo();
768 //throw new Exception("Error: Invalid Parcel Bitmap");
769 }
770 else
771 {
772 //Valid: Lets set it
773 LandBitmap = bitmap;
774 ForceUpdateLandInfo();
775 }
776 } 779 }
777 780
778 /// <summary> 781 /// <summary>
@@ -786,15 +789,19 @@ namespace OpenSim.Region.CoreModules.World.Land
786 789
787 public bool[,] BasicFullRegionLandBitmap() 790 public bool[,] BasicFullRegionLandBitmap()
788 { 791 {
789 return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); 792 return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY);
790 } 793 }
791 794
792 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) 795 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
793 { 796 {
794 bool[,] tempBitmap = new bool[64,64]; 797 // Empty bitmap for the whole region
798 bool[,] tempBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
795 tempBitmap.Initialize(); 799 tempBitmap.Initialize();
796 800
801 // Fill the bitmap square area specified by state and end
797 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); 802 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
803 // m_log.DebugFormat("{0} GetSquareLandBitmap. tempBitmapSize=<{1},{2}>",
804 // LogHeader, tempBitmap.GetLength(0), tempBitmap.GetLength(1));
798 return tempBitmap; 805 return tempBitmap;
799 } 806 }
800 807
@@ -811,24 +818,20 @@ namespace OpenSim.Region.CoreModules.World.Land
811 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, 818 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
812 bool set_value) 819 bool set_value)
813 { 820 {
814 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
815 {
816 //Throw an exception - The bitmap is not 64x64
817 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
818 }
819
820 int x, y; 821 int x, y;
821 for (y = 0; y < 64; y++) 822 for (y = 0; y < land_bitmap.GetLength(1); y++)
822 { 823 {
823 for (x = 0; x < 64; x++) 824 for (x = 0; x < land_bitmap.GetLength(0); x++)
824 { 825 {
825 if (x >= start_x / 4 && x < end_x / 4 826 if (x >= start_x / landUnit && x < end_x / landUnit
826 && y >= start_y / 4 && y < end_y / 4) 827 && y >= start_y / landUnit && y < end_y / landUnit)
827 { 828 {
828 land_bitmap[x, y] = set_value; 829 land_bitmap[x, y] = set_value;
829 } 830 }
830 } 831 }
831 } 832 }
833 // m_log.DebugFormat("{0} ModifyLandBitmapSquare. startXY=<{1},{2}>, endXY=<{3},{4}>, val={5}, landBitmapSize=<{6},{7}>",
834 // LogHeader, start_x, start_y, end_x, end_y, set_value, land_bitmap.GetLength(0), land_bitmap.GetLength(1));
832 return land_bitmap; 835 return land_bitmap;
833 } 836 }
834 837
@@ -840,21 +843,21 @@ namespace OpenSim.Region.CoreModules.World.Land
840 /// <returns></returns> 843 /// <returns></returns>
841 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) 844 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
842 { 845 {
843 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) 846 if (bitmap_base.GetLength(0) != bitmap_add.GetLength(0)
847 || bitmap_base.GetLength(1) != bitmap_add.GetLength(1)
848 || bitmap_add.Rank != 2
849 || bitmap_base.Rank != 2)
844 { 850 {
845 //Throw an exception - The bitmap is not 64x64 851 throw new Exception(
846 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); 852 String.Format("{0} MergeLandBitmaps. merging maps not same size. baseSizeXY=<{1},{2}>, addSizeXY=<{3},{4}>",
847 } 853 LogHeader, bitmap_base.GetLength(0), bitmap_base.GetLength(1), bitmap_add.GetLength(0), bitmap_add.GetLength(1))
848 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) 854 );
849 {
850 //Throw an exception - The bitmap is not 64x64
851 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
852 } 855 }
853 856
854 int x, y; 857 int x, y;
855 for (y = 0; y < 64; y++) 858 for (y = 0; y < bitmap_base.GetLength(1); y++)
856 { 859 {
857 for (x = 0; x < 64; x++) 860 for (x = 0; x < bitmap_add.GetLength(0); x++)
858 { 861 {
859 if (bitmap_add[x, y]) 862 if (bitmap_add[x, y])
860 { 863 {
@@ -871,13 +874,13 @@ namespace OpenSim.Region.CoreModules.World.Land
871 /// <returns></returns> 874 /// <returns></returns>
872 private byte[] ConvertLandBitmapToBytes() 875 private byte[] ConvertLandBitmapToBytes()
873 { 876 {
874 byte[] tempConvertArr = new byte[512]; 877 byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
875 byte tempByte = 0; 878 byte tempByte = 0;
876 int x, y, i, byteNum = 0; 879 int byteNum = 0;
877 i = 0; 880 int i = 0;
878 for (y = 0; y < 64; y++) 881 for (int y = 0; y < LandBitmap.GetLength(1); y++)
879 { 882 {
880 for (x = 0; x < 64; x++) 883 for (int x = 0; x < LandBitmap.GetLength(0); x++)
881 { 884 {
882 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); 885 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
883 if (i % 8 == 0) 886 if (i % 8 == 0)
@@ -889,30 +892,52 @@ namespace OpenSim.Region.CoreModules.World.Land
889 } 892 }
890 } 893 }
891 } 894 }
895 // m_log.DebugFormat("{0} ConvertLandBitmapToBytes. BitmapSize=<{1},{2}>",
896 // LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
892 return tempConvertArr; 897 return tempConvertArr;
893 } 898 }
894 899
895 private bool[,] ConvertBytesToLandBitmap() 900 private bool[,] ConvertBytesToLandBitmap()
896 { 901 {
897 bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; 902 bool[,] tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
898 tempConvertMap.Initialize(); 903 tempConvertMap.Initialize();
899 byte tempByte = 0; 904 byte tempByte = 0;
900 int x = 0, y = 0, i = 0, bitNum = 0; 905 // Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
901 for (i = 0; i < 512; i++) 906 int bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8);
907 int xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit);
908
909 if (bitmapLen == 512)
910 {
911 // Legacy bitmap being passed in. Use the legacy region size
912 // and only set the lower area of the larger region.
913 xLen = (int)(Constants.RegionSize / landUnit);
914 }
915 // m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen);
916
917 int x = 0, y = 0;
918 for (int i = 0; i < bitmapLen; i++)
902 { 919 {
903 tempByte = LandData.Bitmap[i]; 920 tempByte = LandData.Bitmap[i];
904 for (bitNum = 0; bitNum < 8; bitNum++) 921 for (int bitNum = 0; bitNum < 8; bitNum++)
905 { 922 {
906 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); 923 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
907 tempConvertMap[x, y] = bit; 924 try
925 {
926 tempConvertMap[x, y] = bit;
927 }
928 catch (Exception e)
929 {
930 m_log.DebugFormat("{0} ConvertBytestoLandBitmap: i={1}, x={2}, y={3}", LogHeader, i, x, y);
931 }
908 x++; 932 x++;
909 if (x > 63) 933 if (x >= xLen)
910 { 934 {
911 x = 0; 935 x = 0;
912 y++; 936 y++;
913 } 937 }
914 } 938 }
915 } 939 }
940
916 return tempConvertMap; 941 return tempConvertMap;
917 } 942 }
918 943
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index f8e93e1..45617fc 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -1571,10 +1571,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
1571 float X = position.X; 1571 float X = position.X;
1572 float Y = position.Y; 1572 float Y = position.Y;
1573 1573
1574 if (X > ((int)Constants.RegionSize - 1)) 1574 if (X > ((int)m_scene.RegionInfo.RegionSizeX - 1))
1575 X = ((int)Constants.RegionSize - 1); 1575 X = ((int)m_scene.RegionInfo.RegionSizeX - 1);
1576 if (Y > ((int)Constants.RegionSize - 1)) 1576 if (Y > ((int)m_scene.RegionInfo.RegionSizeY - 1))
1577 Y = ((int)Constants.RegionSize - 1); 1577 Y = ((int)m_scene.RegionInfo.RegionSizeY - 1);
1578 if (X < 0) 1578 if (X < 0)
1579 X = 0; 1579 X = 0;
1580 if (Y < 0) 1580 if (Y < 0)
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs b/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs
index 7186dd7..89087b1 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/Effects/DefaultTerrainGenerator.cs
@@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Effects
42 for (y = 0; y < map.Height; y++) 42 for (y = 0; y < map.Height; y++)
43 { 43 {
44 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10; 44 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
45 double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01; 45 double spherFac = TerrainUtil.SphericalFactor(x, y, map.Width / 2, map.Height / 2, 50) * 0.01;
46 if (map[x, y] < spherFac) 46 if (map[x, y] < spherFac)
47 { 47 {
48 map[x, y] = spherFac; 48 map[x, y] = spherFac;
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
index d78ade5..d5c77ec 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
67 { 67 {
68 using (Bitmap bitmap = new Bitmap(filename)) 68 using (Bitmap bitmap = new Bitmap(filename))
69 { 69 {
70 ITerrainChannel retval = new TerrainChannel(true); 70 ITerrainChannel retval = new TerrainChannel(w, h);
71 71
72 for (int x = 0; x < retval.Width; x++) 72 for (int x = 0; x < retval.Width; x++)
73 { 73 {
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index fd30c46..9766bfe 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -30,10 +30,14 @@ using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Reflection; 31using System.Reflection;
32using System.Net; 32using System.Net;
33
33using log4net; 34using log4net;
34using Nini.Config; 35using Nini.Config;
36
35using OpenMetaverse; 37using OpenMetaverse;
36using Mono.Addins; 38using Mono.Addins;
39
40using OpenSim.Data;
37using OpenSim.Framework; 41using OpenSim.Framework;
38using OpenSim.Region.CoreModules.Framework.InterfaceCommander; 42using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
39using OpenSim.Region.CoreModules.World.Terrain.FileLoaders; 43using OpenSim.Region.CoreModules.World.Terrain.FileLoaders;
@@ -70,6 +74,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
70 #endregion 74 #endregion
71 75
72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 private static readonly string LogHeader = "[TERRAIN MODULE]";
73 78
74 private readonly Commander m_commander = new Commander("terrain"); 79 private readonly Commander m_commander = new Commander("terrain");
75 80
@@ -130,15 +135,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain
130 { 135 {
131 if (m_scene.Heightmap == null) 136 if (m_scene.Heightmap == null)
132 { 137 {
133 m_channel = new TerrainChannel(m_InitialTerrain); 138 m_channel = new TerrainChannel(m_InitialTerrain, (int)m_scene.RegionInfo.RegionSizeX,
139 (int)m_scene.RegionInfo.RegionSizeY,
140 (int)m_scene.RegionInfo.RegionSizeZ);
134 m_scene.Heightmap = m_channel; 141 m_scene.Heightmap = m_channel;
135 m_revert = new TerrainChannel();
136 UpdateRevertMap(); 142 UpdateRevertMap();
137 } 143 }
138 else 144 else
139 { 145 {
140 m_channel = m_scene.Heightmap; 146 m_channel = m_scene.Heightmap;
141 m_revert = new TerrainChannel();
142 UpdateRevertMap(); 147 UpdateRevertMap();
143 } 148 }
144 149
@@ -230,11 +235,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
230 try 235 try
231 { 236 {
232 ITerrainChannel channel = loader.Value.LoadFile(filename); 237 ITerrainChannel channel = loader.Value.LoadFile(filename);
233 if (channel.Width != Constants.RegionSize || channel.Height != Constants.RegionSize) 238 if (channel.Width != m_scene.RegionInfo.RegionSizeX || channel.Height != m_scene.RegionInfo.RegionSizeY)
234 { 239 {
235 // TerrainChannel expects a RegionSize x RegionSize map, currently 240 // TerrainChannel expects a RegionSize x RegionSize map, currently
236 throw new ArgumentException(String.Format("wrong size, use a file with size {0} x {1}", 241 throw new ArgumentException(String.Format("wrong size, use a file with size {0} x {1}",
237 Constants.RegionSize, Constants.RegionSize)); 242 m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY));
238 } 243 }
239 m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height); 244 m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height);
240 m_scene.Heightmap = channel; 245 m_scene.Heightmap = channel;
@@ -532,6 +537,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
532 /// </summary> 537 /// </summary>
533 public void UpdateRevertMap() 538 public void UpdateRevertMap()
534 { 539 {
540 /*
535 int x; 541 int x;
536 for (x = 0; x < m_channel.Width; x++) 542 for (x = 0; x < m_channel.Width; x++)
537 { 543 {
@@ -541,6 +547,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
541 m_revert[x, y] = m_channel[x, y]; 547 m_revert[x, y] = m_channel[x, y];
542 } 548 }
543 } 549 }
550 */
551 m_revert = m_channel.MakeCopy();
544 } 552 }
545 553
546 /// <summary> 554 /// <summary>
@@ -567,8 +575,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
567 { 575 {
568 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, 576 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY,
569 fileWidth, fileHeight, 577 fileWidth, fileHeight,
570 (int) Constants.RegionSize, 578 (int) m_scene.RegionInfo.RegionSizeX,
571 (int) Constants.RegionSize); 579 (int) m_scene.RegionInfo.RegionSizeY);
572 m_scene.Heightmap = channel; 580 m_scene.Heightmap = channel;
573 m_channel = channel; 581 m_channel = channel;
574 UpdateRevertMap(); 582 UpdateRevertMap();
@@ -615,8 +623,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
615 { 623 {
616 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, 624 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
617 fileWidth, fileHeight, 625 fileWidth, fileHeight,
618 (int)Constants.RegionSize, 626 (int)m_scene.RegionInfo.RegionSizeX,
619 (int)Constants.RegionSize); 627 (int)m_scene.RegionInfo.RegionSizeY);
620 628
621 MainConsole.Instance.OutputFormat( 629 MainConsole.Instance.OutputFormat(
622 "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}", 630 "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}",
@@ -705,7 +713,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
705 private void CheckForTerrainUpdates(bool respectEstateSettings) 713 private void CheckForTerrainUpdates(bool respectEstateSettings)
706 { 714 {
707 bool shouldTaint = false; 715 bool shouldTaint = false;
708 float[] serialised = m_channel.GetFloatsSerialised(); 716 float[] terrHeights = m_channel.GetFloatsSerialised();
709 int x; 717 int x;
710 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize) 718 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize)
711 { 719 {
@@ -714,16 +722,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain
714 { 722 {
715 if (m_channel.Tainted(x, y)) 723 if (m_channel.Tainted(x, y))
716 { 724 {
717 // if we should respect the estate settings then 725 // If we should respect the estate settings then
718 // fixup and height deltas that don't respect them 726 // fixup and height deltas that don't respect them.
727 // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values.
719 if (respectEstateSettings && LimitChannelChanges(x, y)) 728 if (respectEstateSettings && LimitChannelChanges(x, y))
720 { 729 {
721 // this has been vetoed, so update 730 // Terrain heights were modified. Refetch the terrain info.
722 // what we are going to send to the client 731 terrHeights = m_channel.GetFloatsSerialised();
723 serialised = m_channel.GetFloatsSerialised();
724 } 732 }
725 733
726 SendToClients(serialised, x, y); 734 // m_log.DebugFormat("{0} Patch modified. Sending (x,y) = ({1},{2})", LogHeader, x, y);
735 SendToClients(terrHeights, x, y);
727 shouldTaint = true; 736 shouldTaint = true;
728 } 737 }
729 } 738 }
@@ -792,13 +801,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
792 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param> 801 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
793 /// <param name="x">The patch corner to send</param> 802 /// <param name="x">The patch corner to send</param>
794 /// <param name="y">The patch corner to send</param> 803 /// <param name="y">The patch corner to send</param>
795 private void SendToClients(float[] serialised, int x, int y) 804 private void SendToClients(float[] heightMap, int x, int y)
796 { 805 {
797 m_scene.ForEachClient( 806 m_scene.ForEachClient(
798 delegate(IClientAPI controller) 807 delegate(IClientAPI controller)
799 { controller.SendLayerData( 808 { controller.SendLayerData( x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, heightMap); }
800 x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised);
801 }
802 ); 809 );
803 } 810 }
804 811
@@ -984,28 +991,28 @@ namespace OpenSim.Region.CoreModules.World.Terrain
984 991
985 if (direction.ToLower().StartsWith("y")) 992 if (direction.ToLower().StartsWith("y"))
986 { 993 {
987 for (int x = 0; x < Constants.RegionSize; x++) 994 for (int x = 0; x < m_channel.Width; x++)
988 { 995 {
989 for (int y = 0; y < Constants.RegionSize / 2; y++) 996 for (int y = 0; y < m_channel.Height / 2; y++)
990 { 997 {
991 double height = m_channel[x, y]; 998 double height = m_channel[x, y];
992 double flippedHeight = m_channel[x, (int)Constants.RegionSize - 1 - y]; 999 double flippedHeight = m_channel[x, (int)m_channel.Height - 1 - y];
993 m_channel[x, y] = flippedHeight; 1000 m_channel[x, y] = flippedHeight;
994 m_channel[x, (int)Constants.RegionSize - 1 - y] = height; 1001 m_channel[x, (int)m_channel.Height - 1 - y] = height;
995 1002
996 } 1003 }
997 } 1004 }
998 } 1005 }
999 else if (direction.ToLower().StartsWith("x")) 1006 else if (direction.ToLower().StartsWith("x"))
1000 { 1007 {
1001 for (int y = 0; y < Constants.RegionSize; y++) 1008 for (int y = 0; y < m_channel.Height; y++)
1002 { 1009 {
1003 for (int x = 0; x < Constants.RegionSize / 2; x++) 1010 for (int x = 0; x < m_channel.Width / 2; x++)
1004 { 1011 {
1005 double height = m_channel[x, y]; 1012 double height = m_channel[x, y];
1006 double flippedHeight = m_channel[(int)Constants.RegionSize - 1 - x, y]; 1013 double flippedHeight = m_channel[(int)m_channel.Width - 1 - x, y];
1007 m_channel[x, y] = flippedHeight; 1014 m_channel[x, y] = flippedHeight;
1008 m_channel[(int)Constants.RegionSize - 1 - x, y] = height; 1015 m_channel[(int)m_channel.Width - 1 - x, y] = height;
1009 1016
1010 } 1017 }
1011 } 1018 }
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index cdf1467..cd315b1 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -803,7 +803,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
803 if (httpserver.Length == 0) 803 if (httpserver.Length == 0)
804 { 804 {
805 uint x = 0, y = 0; 805 uint x = 0, y = 0;
806 Utils.LongToUInts(regionhandle, out x, out y); 806 Util.RegionHandleToWorldLoc(regionhandle, out x, out y);
807 GridRegion mreg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); 807 GridRegion mreg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y);
808 808
809 if (mreg != null) 809 if (mreg != null)