diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 209 |
1 files changed, 185 insertions, 24 deletions
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 9b0e2ff..6c6aa37 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -213,7 +213,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
213 | UUID agentID, Caps caps) | 213 | UUID agentID, Caps caps) |
214 | { | 214 | { |
215 | //try | 215 | //try |
216 | //{ | 216 | // |
217 | //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", | 217 | //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", |
218 | // path, param, agentID.ToString()); | 218 | // path, param, agentID.ToString()); |
219 | 219 | ||
@@ -263,7 +263,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
263 | foreach (GridRegion r in regions) | 263 | foreach (GridRegion r in regions) |
264 | { | 264 | { |
265 | MapBlockData block = new MapBlockData(); | 265 | MapBlockData block = new MapBlockData(); |
266 | MapBlockFromGridRegion(block, r); | 266 | MapBlockFromGridRegion(block, r, 0); |
267 | mapBlocks.Add(block); | 267 | mapBlocks.Add(block); |
268 | } | 268 | } |
269 | avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); | 269 | avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); |
@@ -373,7 +373,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
373 | public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, | 373 | public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, |
374 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle) | 374 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle) |
375 | { | 375 | { |
376 | // m_log.DebugFormat("[WORLD MAP]: Handle MapItem request {0} {1}", regionhandle, itemtype); | 376 | m_log.DebugFormat("[WORLD MAP]: Handle MapItem request {0} {1}", regionhandle, itemtype); |
377 | 377 | ||
378 | lock (m_rootAgents) | 378 | lock (m_rootAgents) |
379 | { | 379 | { |
@@ -429,7 +429,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
429 | // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes. | 429 | // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes. |
430 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); | 430 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); |
431 | } | 431 | } |
432 | } else if (itemtype == 7) // Service 7 (MAP_ITEM_LAND_FOR_SALE) | 432 | } |
433 | else if (itemtype == 7) // Service 7 (MAP_ITEM_LAND_FOR_SALE) | ||
433 | { | 434 | { |
434 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) | 435 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) |
435 | { | 436 | { |
@@ -463,7 +464,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
463 | mapitem.x = (uint)(xstart + x); | 464 | mapitem.x = (uint)(xstart + x); |
464 | mapitem.y = (uint)(ystart + y); | 465 | mapitem.y = (uint)(ystart + y); |
465 | // mapitem.z = (uint)m_scene.GetGroundHeight(x,y); | 466 | // mapitem.z = (uint)m_scene.GetGroundHeight(x,y); |
466 | mapitem.id = UUID.Zero; | 467 | mapitem.id = parcel.GlobalID; |
467 | mapitem.name = parcel.Name; | 468 | mapitem.name = parcel.Name; |
468 | mapitem.Extra = parcel.Area; | 469 | mapitem.Extra = parcel.Area; |
469 | mapitem.Extra2 = parcel.SalePrice; | 470 | mapitem.Extra2 = parcel.SalePrice; |
@@ -481,6 +482,34 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
481 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); | 482 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); |
482 | } | 483 | } |
483 | } | 484 | } |
485 | else if (itemtype == 1) // Service 1 (MAP_ITEM_TELEHUB) | ||
486 | { | ||
487 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) | ||
488 | { | ||
489 | List<mapItemReply> mapitems = new List<mapItemReply>(); | ||
490 | mapItemReply mapitem = new mapItemReply(); | ||
491 | |||
492 | SceneObjectGroup sog = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject); | ||
493 | if (sog != null) | ||
494 | { | ||
495 | mapitem = new mapItemReply(); | ||
496 | mapitem.x = (uint)(xstart + sog.AbsolutePosition.X); | ||
497 | mapitem.y = (uint)(ystart + sog.AbsolutePosition.Y); | ||
498 | mapitem.id = UUID.Zero; | ||
499 | mapitem.name = sog.Name; | ||
500 | mapitem.Extra = 0; // color (not used) | ||
501 | mapitem.Extra2 = 0; // 0 = telehub / 1 = infohub | ||
502 | mapitems.Add(mapitem); | ||
503 | |||
504 | remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); | ||
505 | } | ||
506 | } | ||
507 | else | ||
508 | { | ||
509 | // Remote Map Item Request | ||
510 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); | ||
511 | } | ||
512 | } | ||
484 | } | 513 | } |
485 | 514 | ||
486 | private int nAsyncRequests = 0; | 515 | private int nAsyncRequests = 0; |
@@ -620,6 +649,28 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
620 | } | 649 | } |
621 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); | 650 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); |
622 | } | 651 | } |
652 | |||
653 | // Service 1 (MAP_ITEM_TELEHUB) | ||
654 | itemtype = 1; | ||
655 | |||
656 | if (response.ContainsKey(itemtype.ToString())) | ||
657 | { | ||
658 | List<mapItemReply> returnitems = new List<mapItemReply>(); | ||
659 | OSDArray itemarray = (OSDArray)response[itemtype.ToString()]; | ||
660 | for (int i = 0; i < itemarray.Count; i++) | ||
661 | { | ||
662 | OSDMap mapitem = (OSDMap)itemarray[i]; | ||
663 | mapItemReply mi = new mapItemReply(); | ||
664 | mi.x = (uint)mapitem["X"].AsInteger(); | ||
665 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
666 | mi.id = mapitem["ID"].AsUUID(); | ||
667 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
668 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
669 | mi.name = mapitem["Name"].AsString(); | ||
670 | returnitems.Add(mi); | ||
671 | } | ||
672 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); | ||
673 | } | ||
623 | } | 674 | } |
624 | } | 675 | } |
625 | } | 676 | } |
@@ -904,8 +955,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
904 | { | 955 | { |
905 | List<MapBlockData> response = new List<MapBlockData>(); | 956 | List<MapBlockData> response = new List<MapBlockData>(); |
906 | 957 | ||
907 | // this should return one mapblock at most. | 958 | // this should return one mapblock at most. It is triggered by a click |
908 | // (diva note: why?? in that case we should GetRegionByPosition) | 959 | // on an unloaded square. |
909 | // But make sure: Look whether the one we requested is in there | 960 | // But make sure: Look whether the one we requested is in there |
910 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, | 961 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, |
911 | minX * (int)Constants.RegionSize, | 962 | minX * (int)Constants.RegionSize, |
@@ -922,7 +973,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
922 | { | 973 | { |
923 | // found it => add it to response | 974 | // found it => add it to response |
924 | MapBlockData block = new MapBlockData(); | 975 | MapBlockData block = new MapBlockData(); |
925 | MapBlockFromGridRegion(block, r); | 976 | MapBlockFromGridRegion(block, r, flag); |
926 | response.Add(block); | 977 | response.Add(block); |
927 | break; | 978 | break; |
928 | } | 979 | } |
@@ -938,10 +989,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
938 | block.Access = 254; // means 'simulator is offline' | 989 | block.Access = 254; // means 'simulator is offline' |
939 | response.Add(block); | 990 | response.Add(block); |
940 | } | 991 | } |
941 | if ((flag & 2) == 2) // V2 !!! | 992 | // The lower 16 bits are an unsigned int16 |
942 | remoteClient.SendMapBlock(response, 2); | 993 | remoteClient.SendMapBlock(response, flag & 0xffff); |
943 | else | ||
944 | remoteClient.SendMapBlock(response, 0); | ||
945 | } | 994 | } |
946 | else | 995 | else |
947 | { | 996 | { |
@@ -961,21 +1010,29 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
961 | foreach (GridRegion r in regions) | 1010 | foreach (GridRegion r in regions) |
962 | { | 1011 | { |
963 | MapBlockData block = new MapBlockData(); | 1012 | MapBlockData block = new MapBlockData(); |
964 | MapBlockFromGridRegion(block, r); | 1013 | MapBlockFromGridRegion(block, r, flag); |
965 | mapBlocks.Add(block); | 1014 | mapBlocks.Add(block); |
966 | } | 1015 | } |
967 | if ((flag & 2) == 2) // V2 !!! | 1016 | remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); |
968 | remoteClient.SendMapBlock(mapBlocks, 2); | ||
969 | else | ||
970 | remoteClient.SendMapBlock(mapBlocks, 0); | ||
971 | 1017 | ||
972 | return mapBlocks; | 1018 | return mapBlocks; |
973 | } | 1019 | } |
974 | 1020 | ||
975 | protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r) | 1021 | protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) |
976 | { | 1022 | { |
977 | block.Access = r.Access; | 1023 | block.Access = r.Access; |
978 | block.MapImageId = r.TerrainImage; | 1024 | switch (flag & 0xffff) |
1025 | { | ||
1026 | case 0: | ||
1027 | block.MapImageId = r.TerrainImage; | ||
1028 | break; | ||
1029 | case 2: | ||
1030 | block.MapImageId = r.ParcelImage; | ||
1031 | break; | ||
1032 | default: | ||
1033 | block.MapImageId = UUID.Zero; | ||
1034 | break; | ||
1035 | } | ||
979 | block.Name = r.RegionName; | 1036 | block.Name = r.RegionName; |
980 | block.X = (ushort)(r.RegionLocX / Constants.RegionSize); | 1037 | block.X = (ushort)(r.RegionLocX / Constants.RegionSize); |
981 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); | 1038 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); |
@@ -1109,7 +1166,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1109 | foreach (GridRegion r in regions) | 1166 | foreach (GridRegion r in regions) |
1110 | { | 1167 | { |
1111 | MapBlockData mapBlock = new MapBlockData(); | 1168 | MapBlockData mapBlock = new MapBlockData(); |
1112 | MapBlockFromGridRegion(mapBlock, r); | 1169 | MapBlockFromGridRegion(mapBlock, r, 0); |
1113 | AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); | 1170 | AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); |
1114 | 1171 | ||
1115 | if (texAsset != null) | 1172 | if (texAsset != null) |
@@ -1240,7 +1297,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1240 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + x)); | 1297 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + x)); |
1241 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + y)); | 1298 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + y)); |
1242 | // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y)); | 1299 | // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y)); |
1243 | responsemapdata["ID"] = OSD.FromUUID(UUID.Zero); | 1300 | responsemapdata["ID"] = OSD.FromUUID(parcel.GlobalID); |
1244 | responsemapdata["Name"] = OSD.FromString(parcel.Name); | 1301 | responsemapdata["Name"] = OSD.FromString(parcel.Name); |
1245 | responsemapdata["Extra"] = OSD.FromInteger(parcel.Area); | 1302 | responsemapdata["Extra"] = OSD.FromInteger(parcel.Area); |
1246 | responsemapdata["Extra2"] = OSD.FromInteger(parcel.SalePrice); | 1303 | responsemapdata["Extra2"] = OSD.FromInteger(parcel.SalePrice); |
@@ -1250,6 +1307,26 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1250 | responsemap["7"] = responsearr; | 1307 | responsemap["7"] = responsearr; |
1251 | } | 1308 | } |
1252 | 1309 | ||
1310 | if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero) | ||
1311 | { | ||
1312 | SceneObjectGroup sog = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject); | ||
1313 | if (sog != null) | ||
1314 | { | ||
1315 | OSDArray responsearr = new OSDArray(); | ||
1316 | OSDMap responsemapdata = new OSDMap(); | ||
1317 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + sog.AbsolutePosition.X)); | ||
1318 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + sog.AbsolutePosition.Y)); | ||
1319 | // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y)); | ||
1320 | responsemapdata["ID"] = OSD.FromUUID(sog.UUID); | ||
1321 | responsemapdata["Name"] = OSD.FromString(sog.Name); | ||
1322 | responsemapdata["Extra"] = OSD.FromInteger(0); // color (unused) | ||
1323 | responsemapdata["Extra2"] = OSD.FromInteger(0); // 0 = telehub / 1 = infohub | ||
1324 | responsearr.Add(responsemapdata); | ||
1325 | |||
1326 | responsemap["1"] = responsearr; | ||
1327 | } | ||
1328 | } | ||
1329 | |||
1253 | return responsemap; | 1330 | return responsemap; |
1254 | } | 1331 | } |
1255 | 1332 | ||
@@ -1268,9 +1345,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1268 | if (data == null) | 1345 | if (data == null) |
1269 | return; | 1346 | return; |
1270 | 1347 | ||
1348 | byte[] overlay = GenerateOverlay(); | ||
1349 | |||
1271 | m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); | 1350 | m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); |
1272 | 1351 | ||
1273 | UUID terrainImageID = UUID.Random(); | 1352 | UUID terrainImageID = UUID.Random(); |
1353 | UUID parcelImageID = UUID.Zero; | ||
1274 | 1354 | ||
1275 | AssetBase asset = new AssetBase( | 1355 | AssetBase asset = new AssetBase( |
1276 | terrainImageID, | 1356 | terrainImageID, |
@@ -1286,14 +1366,35 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1286 | m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); | 1366 | m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); |
1287 | m_scene.AssetService.Store(asset); | 1367 | m_scene.AssetService.Store(asset); |
1288 | 1368 | ||
1369 | if (overlay != null) | ||
1370 | { | ||
1371 | parcelImageID = UUID.Random(); | ||
1372 | |||
1373 | AssetBase parcels = new AssetBase( | ||
1374 | parcelImageID, | ||
1375 | "parcelImage_" + m_scene.RegionInfo.RegionID.ToString(), | ||
1376 | (sbyte)AssetType.Texture, | ||
1377 | m_scene.RegionInfo.RegionID.ToString()); | ||
1378 | parcels.Data = overlay; | ||
1379 | parcels.Description = m_scene.RegionInfo.RegionName; | ||
1380 | parcels.Temporary = false; | ||
1381 | parcels.Flags = AssetFlags.Maptile; | ||
1382 | |||
1383 | m_scene.AssetService.Store(parcels); | ||
1384 | } | ||
1385 | |||
1289 | // Switch to the new one | 1386 | // Switch to the new one |
1290 | UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID; | 1387 | UUID lastTerrainImageID = m_scene.RegionInfo.RegionSettings.TerrainImageID; |
1388 | UUID lastParcelImageID = m_scene.RegionInfo.RegionSettings.ParcelImageID; | ||
1291 | m_scene.RegionInfo.RegionSettings.TerrainImageID = terrainImageID; | 1389 | m_scene.RegionInfo.RegionSettings.TerrainImageID = terrainImageID; |
1390 | m_scene.RegionInfo.RegionSettings.ParcelImageID = parcelImageID; | ||
1292 | m_scene.RegionInfo.RegionSettings.Save(); | 1391 | m_scene.RegionInfo.RegionSettings.Save(); |
1293 | 1392 | ||
1294 | // Delete the old one | 1393 | // Delete the old one |
1295 | m_log.DebugFormat("[WORLDMAP]: Deleting old map tile {0}", lastMapRegionUUID); | 1394 | // m_log.DebugFormat("[WORLDMAP]: Deleting old map tile {0}", lastTerrainImageID); |
1296 | m_scene.AssetService.Delete(lastMapRegionUUID.ToString()); | 1395 | m_scene.AssetService.Delete(lastTerrainImageID.ToString()); |
1396 | if (lastParcelImageID != UUID.Zero) | ||
1397 | m_scene.AssetService.Delete(lastParcelImageID.ToString()); | ||
1297 | } | 1398 | } |
1298 | 1399 | ||
1299 | private void MakeRootAgent(ScenePresence avatar) | 1400 | private void MakeRootAgent(ScenePresence avatar) |
@@ -1339,6 +1440,66 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1339 | } | 1440 | } |
1340 | } | 1441 | } |
1341 | 1442 | ||
1443 | private Byte[] GenerateOverlay() | ||
1444 | { | ||
1445 | Bitmap overlay = new Bitmap(256, 256); | ||
1446 | |||
1447 | bool[,] saleBitmap = new bool[64, 64]; | ||
1448 | for (int x = 0 ; x < 64 ; x++) | ||
1449 | { | ||
1450 | for (int y = 0 ; y < 64 ; y++) | ||
1451 | saleBitmap[x, y] = false; | ||
1452 | } | ||
1453 | |||
1454 | bool landForSale = false; | ||
1455 | |||
1456 | List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); | ||
1457 | |||
1458 | Color background = Color.FromArgb(0, 0, 0, 0); | ||
1459 | SolidBrush transparent = new SolidBrush(background); | ||
1460 | Graphics g = Graphics.FromImage(overlay); | ||
1461 | g.FillRectangle(transparent, 0, 0, 256, 256); | ||
1462 | |||
1463 | SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); | ||
1464 | |||
1465 | foreach (ILandObject land in parcels) | ||
1466 | { | ||
1467 | // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); | ||
1468 | if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) | ||
1469 | { | ||
1470 | landForSale = true; | ||
1471 | |||
1472 | saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); | ||
1473 | } | ||
1474 | } | ||
1475 | |||
1476 | if (!landForSale) | ||
1477 | { | ||
1478 | m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not geenrating overlay", m_scene.RegionInfo.RegionName); | ||
1479 | return null; | ||
1480 | } | ||
1481 | |||
1482 | m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, genrating overlay", m_scene.RegionInfo.RegionName); | ||
1483 | |||
1484 | for (int x = 0 ; x < 64 ; x++) | ||
1485 | { | ||
1486 | for (int y = 0 ; y < 64 ; y++) | ||
1487 | { | ||
1488 | if (saleBitmap[x, y]) | ||
1489 | g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); | ||
1490 | } | ||
1491 | } | ||
1492 | |||
1493 | try | ||
1494 | { | ||
1495 | return OpenJPEG.EncodeFromImage(overlay, true); | ||
1496 | } | ||
1497 | catch (Exception e) | ||
1498 | { | ||
1499 | m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); | ||
1500 | } | ||
1501 | return null; | ||
1502 | } | ||
1342 | } | 1503 | } |
1343 | 1504 | ||
1344 | public struct MapRequestState | 1505 | public struct MapRequestState |