diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 228 |
1 files changed, 143 insertions, 85 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 8c327d8..c57e7bb 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -998,6 +998,39 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
998 | } | 998 | } |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | public ILandObject GetLandObjectinLandUnits(int x, int y) | ||
1002 | { | ||
1003 | if (m_landList.Count == 0 || m_landIDList == null) | ||
1004 | return null; | ||
1005 | |||
1006 | lock (m_landIDList) | ||
1007 | { | ||
1008 | try | ||
1009 | { | ||
1010 | return m_landList[m_landIDList[x, y]]; | ||
1011 | } | ||
1012 | catch (IndexOutOfRangeException) | ||
1013 | { | ||
1014 | return null; | ||
1015 | } | ||
1016 | } | ||
1017 | } | ||
1018 | |||
1019 | public int GetLandObjectIDinLandUnits(int x, int y) | ||
1020 | { | ||
1021 | lock (m_landIDList) | ||
1022 | { | ||
1023 | try | ||
1024 | { | ||
1025 | return m_landIDList[x, y]; | ||
1026 | } | ||
1027 | catch (IndexOutOfRangeException) | ||
1028 | { | ||
1029 | return -1; | ||
1030 | } | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1001 | // Create a 'parcel is here' bitmap for the parcel identified by the passed landID | 1034 | // Create a 'parcel is here' bitmap for the parcel identified by the passed landID |
1002 | private bool[,] CreateBitmapForID(int landID) | 1035 | private bool[,] CreateBitmapForID(int landID) |
1003 | { | 1036 | { |
@@ -1282,18 +1315,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1282 | #region Parcel Updating | 1315 | #region Parcel Updating |
1283 | 1316 | ||
1284 | /// <summary> | 1317 | /// <summary> |
1285 | /// Send the parcel overlay blocks to the client. We send the overlay packets | 1318 | /// Send the parcel overlay blocks to the client. |
1286 | /// around a location and limited by the 'parcelLayerViewDistance'. This number | ||
1287 | /// is usually 128 and the code is arranged so it sends all the parcel overlay | ||
1288 | /// information for a whole region if the region is legacy sized (256x256). If | ||
1289 | /// the region is larger, only the parcel layer information is sent around | ||
1290 | /// the point specified. This reduces the problem of parcel layer information | ||
1291 | /// blocks increasing exponentially as region size increases. | ||
1292 | /// </summary> | 1319 | /// </summary> |
1293 | /// <param name="remote_client">The object representing the client</param> | 1320 | /// <param name="remote_client">The object representing the client</param> |
1294 | /// <param name="xPlace">X position in the region to send surrounding parcel layer info</param> | ||
1295 | /// <param name="yPlace">y position in the region to send surrounding parcel layer info</param> | ||
1296 | /// <param name="layerViewDistance">Distance from x,y position to send parcel layer info</param> | ||
1297 | public void SendParcelOverlay(IClientAPI remote_client) | 1321 | public void SendParcelOverlay(IClientAPI remote_client) |
1298 | { | 1322 | { |
1299 | if (remote_client.SceneAgent.PresenceType == PresenceType.Npc) | 1323 | if (remote_client.SceneAgent.PresenceType == PresenceType.Npc) |
@@ -1301,99 +1325,133 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1301 | 1325 | ||
1302 | const int LAND_BLOCKS_PER_PACKET = 1024; | 1326 | const int LAND_BLOCKS_PER_PACKET = 1024; |
1303 | 1327 | ||
1328 | int curID; | ||
1329 | int southID; | ||
1330 | |||
1304 | byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | 1331 | byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; |
1305 | int byteArrayCount = 0; | 1332 | int byteArrayCount = 0; |
1306 | int sequenceID = 0; | 1333 | int sequenceID = 0; |
1307 | 1334 | ||
1335 | int sx = (int)m_scene.RegionInfo.RegionSizeX / LandUnit; | ||
1336 | byte curByte; | ||
1337 | byte tmpByte; | ||
1338 | |||
1308 | // Layer data is in LandUnit (4m) chunks | 1339 | // Layer data is in LandUnit (4m) chunks |
1309 | for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y += LandUnit) | 1340 | for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / LandUnit; ++y) |
1310 | { | 1341 | { |
1311 | for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x += LandUnit) | 1342 | for (int x = 0; x < sx;) |
1312 | { | 1343 | { |
1313 | byte tempByte = 0; //This represents the byte for the current 4x4 | 1344 | curID = GetLandObjectIDinLandUnits(x,y); |
1345 | if(curID < 0) | ||
1346 | continue; | ||
1314 | 1347 | ||
1315 | ILandObject currentParcelBlock = GetLandObject(x, y); | 1348 | ILandObject currentParcel = GetLandObject(curID); |
1349 | if (currentParcel == null) | ||
1350 | continue; | ||
1316 | 1351 | ||
1317 | if (currentParcelBlock != null) | 1352 | // types |
1353 | if (currentParcel.LandData.OwnerID == remote_client.AgentId) | ||
1318 | { | 1354 | { |
1319 | // types | 1355 | //Owner Flag |
1320 | if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) | 1356 | curByte = LandChannel.LAND_TYPE_OWNED_BY_REQUESTER; |
1321 | { | 1357 | } |
1322 | //Owner Flag | 1358 | else if (currentParcel.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcel.LandData.GroupID)) |
1323 | tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_REQUESTER; | 1359 | { |
1324 | } | 1360 | curByte = LandChannel.LAND_TYPE_OWNED_BY_GROUP; |
1325 | else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID)) | 1361 | } |
1326 | { | 1362 | else if (currentParcel.LandData.SalePrice > 0 && |
1327 | tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_GROUP; | 1363 | (currentParcel.LandData.AuthBuyerID == UUID.Zero || |
1328 | } | 1364 | currentParcel.LandData.AuthBuyerID == remote_client.AgentId)) |
1329 | else if (currentParcelBlock.LandData.SalePrice > 0 && | 1365 | { |
1330 | (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || | 1366 | //Sale type |
1331 | currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) | 1367 | curByte = LandChannel.LAND_TYPE_IS_FOR_SALE; |
1332 | { | 1368 | } |
1333 | //Sale type | 1369 | else if (currentParcel.LandData.OwnerID == UUID.Zero) |
1334 | tempByte = (byte)LandChannel.LAND_TYPE_IS_FOR_SALE; | 1370 | { |
1335 | } | 1371 | //Public type |
1336 | else if (currentParcelBlock.LandData.OwnerID == UUID.Zero) | 1372 | curByte = LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero |
1337 | { | 1373 | } |
1338 | //Public type | 1374 | // LAND_TYPE_IS_BEING_AUCTIONED still unsuported |
1339 | tempByte = (byte)LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero | 1375 | else |
1340 | } | 1376 | { |
1341 | // LAND_TYPE_IS_BEING_AUCTIONED still unsuported | 1377 | //Other |
1342 | else | 1378 | curByte = LandChannel.LAND_TYPE_OWNED_BY_OTHER; |
1343 | { | 1379 | } |
1344 | //Other Flag | ||
1345 | tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_OTHER; | ||
1346 | } | ||
1347 | 1380 | ||
1348 | // now flags | 1381 | // now flags |
1349 | // border control | 1382 | // local sound |
1383 | if ((currentParcel.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0) | ||
1384 | curByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND; | ||
1350 | 1385 | ||
1351 | ILandObject westParcel = null; | 1386 | // hide avatars |
1352 | ILandObject southParcel = null; | 1387 | if (!currentParcel.LandData.SeeAVs) |
1353 | if (x > 0) | 1388 | curByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS; |
1354 | { | ||
1355 | westParcel = GetLandObject((x - 1), y); | ||
1356 | } | ||
1357 | if (y > 0) | ||
1358 | { | ||
1359 | southParcel = GetLandObject(x, (y - 1)); | ||
1360 | } | ||
1361 | 1389 | ||
1362 | if (x == 0) | 1390 | // border flags for current |
1363 | { | 1391 | if (y == 0) |
1364 | tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST; | 1392 | { |
1365 | } | 1393 | curByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH; |
1366 | else if (westParcel != null && westParcel != currentParcelBlock) | 1394 | tmpByte = curByte; |
1367 | { | 1395 | } |
1368 | tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST; | 1396 | else |
1369 | } | 1397 | { |
1398 | tmpByte = curByte; | ||
1399 | southID = GetLandObjectIDinLandUnits(x, (y - 1)); | ||
1400 | if (southID > 0 && southID != curID) | ||
1401 | tmpByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH; | ||
1402 | } | ||
1403 | |||
1404 | tmpByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST; | ||
1405 | byteArray[byteArrayCount] = tmpByte; | ||
1406 | byteArrayCount++; | ||
1370 | 1407 | ||
1371 | if (y == 0) | 1408 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) |
1409 | { | ||
1410 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); | ||
1411 | byteArrayCount = 0; | ||
1412 | sequenceID++; | ||
1413 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | ||
1414 | } | ||
1415 | // keep adding while on same parcel, checking south border | ||
1416 | if (y == 0) | ||
1417 | { | ||
1418 | // all have south border and that is already on curByte | ||
1419 | while (++x < sx && GetLandObjectIDinLandUnits(x, y) == curID) | ||
1372 | { | 1420 | { |
1373 | tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH; | 1421 | byteArray[byteArrayCount] = curByte; |
1422 | byteArrayCount++; | ||
1423 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) | ||
1424 | { | ||
1425 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); | ||
1426 | byteArrayCount = 0; | ||
1427 | sequenceID++; | ||
1428 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | ||
1429 | } | ||
1374 | } | 1430 | } |
1375 | else if (southParcel != null && southParcel != currentParcelBlock) | 1431 | } |
1432 | else | ||
1433 | { | ||
1434 | while (++x < sx && GetLandObjectIDinLandUnits(x, y) == curID) | ||
1376 | { | 1435 | { |
1377 | tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH; | 1436 | // need to check south one by one |
1378 | } | 1437 | southID = GetLandObjectIDinLandUnits(x, (y - 1)); |
1379 | 1438 | if (southID > 0 && southID != curID) | |
1380 | // local sound | 1439 | { |
1381 | if ((currentParcelBlock.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0) | 1440 | tmpByte = curByte; |
1382 | tempByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND; | 1441 | tmpByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH; |
1383 | 1442 | byteArray[byteArrayCount] = tmpByte; | |
1384 | // hide avatars | 1443 | } |
1385 | if (!currentParcelBlock.LandData.SeeAVs) | 1444 | else |
1386 | tempByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS; | 1445 | byteArray[byteArrayCount] = curByte; |
1387 | |||
1388 | 1446 | ||
1389 | byteArray[byteArrayCount] = tempByte; | 1447 | byteArrayCount++; |
1390 | byteArrayCount++; | 1448 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) |
1391 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) | 1449 | { |
1392 | { | 1450 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); |
1393 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); | 1451 | byteArrayCount = 0; |
1394 | byteArrayCount = 0; | 1452 | sequenceID++; |
1395 | sequenceID++; | 1453 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; |
1396 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | 1454 | } |
1397 | } | 1455 | } |
1398 | } | 1456 | } |
1399 | } | 1457 | } |