aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs221
1 files changed, 197 insertions, 24 deletions
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index ca5529d9..21e3ecb 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -46,6 +46,7 @@ using OpenSim.Framework.Servers;
46using OpenSim.Framework.Servers.HttpServer; 46using OpenSim.Framework.Servers.HttpServer;
47using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.CoreModules.World.Land;
49using Caps=OpenSim.Framework.Capabilities.Caps; 50using Caps=OpenSim.Framework.Capabilities.Caps;
50using OSDArray=OpenMetaverse.StructuredData.OSDArray; 51using OSDArray=OpenMetaverse.StructuredData.OSDArray;
51using OSDMap=OpenMetaverse.StructuredData.OSDMap; 52using OSDMap=OpenMetaverse.StructuredData.OSDMap;
@@ -68,6 +69,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
68 protected Scene m_scene; 69 protected Scene m_scene;
69 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 70 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
70 private int cachedTime = 0; 71 private int cachedTime = 0;
72 private int blacklistTimeout = 10*60*1000; // 10 minutes
71 private byte[] myMapImageJPEG; 73 private byte[] myMapImageJPEG;
72 protected volatile bool m_Enabled = false; 74 protected volatile bool m_Enabled = false;
73 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>(); 75 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>();
@@ -85,6 +87,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
85 IConfig startupConfig = config.Configs["Startup"]; 87 IConfig startupConfig = config.Configs["Startup"];
86 if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap") 88 if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap")
87 m_Enabled = true; 89 m_Enabled = true;
90
91 blacklistTimeout = startupConfig.GetInt("BlacklistTimeout", 10*60) * 1000;
88 } 92 }
89 93
90 public virtual void AddRegion (Scene scene) 94 public virtual void AddRegion (Scene scene)
@@ -159,11 +163,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
159 m_scene.EventManager.OnClientClosed += ClientLoggedOut; 163 m_scene.EventManager.OnClientClosed += ClientLoggedOut;
160 m_scene.EventManager.OnMakeChildAgent += MakeChildAgent; 164 m_scene.EventManager.OnMakeChildAgent += MakeChildAgent;
161 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; 165 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent;
166 m_scene.EventManager.OnRegionUp += OnRegionUp;
167
168 StartThread(new object());
162 } 169 }
163 170
164 // this has to be called with a lock on m_scene 171 // this has to be called with a lock on m_scene
165 protected virtual void RemoveHandlers() 172 protected virtual void RemoveHandlers()
166 { 173 {
174 StopThread();
175
176 m_scene.EventManager.OnRegionUp -= OnRegionUp;
167 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; 177 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent;
168 m_scene.EventManager.OnMakeChildAgent -= MakeChildAgent; 178 m_scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
169 m_scene.EventManager.OnClientClosed -= ClientLoggedOut; 179 m_scene.EventManager.OnClientClosed -= ClientLoggedOut;
@@ -279,7 +289,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
279 /// <returns></returns> 289 /// <returns></returns>
280 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) 290 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
281 { 291 {
282 m_log.Debug("[WORLD MAP]: MapLayer Request in region: " + m_scene.RegionInfo.RegionName); 292 m_log.DebugFormat("[WORLD MAP]: MapLayer Request in region: {0}", m_scene.RegionInfo.RegionName);
283 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 293 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
284 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 294 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
285 return mapResponse; 295 return mapResponse;
@@ -321,8 +331,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
321 lock (m_rootAgents) 331 lock (m_rootAgents)
322 { 332 {
323 m_rootAgents.Remove(AgentId); 333 m_rootAgents.Remove(AgentId);
324 if (m_rootAgents.Count == 0)
325 StopThread();
326 } 334 }
327 } 335 }
328 #endregion 336 #endregion
@@ -362,6 +370,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
362 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 370 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
363 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 371 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
364 { 372 {
373// m_log.DebugFormat("[WORLD MAP]: Handle MapItem request {0} {1}", regionhandle, itemtype);
374
365 lock (m_rootAgents) 375 lock (m_rootAgents)
366 { 376 {
367 if (!m_rootAgents.Contains(remoteClient.AgentId)) 377 if (!m_rootAgents.Contains(remoteClient.AgentId))
@@ -370,7 +380,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
370 uint xstart = 0; 380 uint xstart = 0;
371 uint ystart = 0; 381 uint ystart = 0;
372 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out xstart, out ystart); 382 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out xstart, out ystart);
373 if (itemtype == 6) // we only sevice 6 right now (avatar green dots) 383 if (itemtype == 6) // Service 6 right now (MAP_ITEM_AGENTS_LOCATION; green dots)
374 { 384 {
375 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) 385 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle)
376 { 386 {
@@ -414,14 +424,57 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
414 // Remote Map Item Request 424 // Remote Map Item Request
415 425
416 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes. 426 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes.
417 // Note that we only start up a remote mapItem Request thread if there's users who could 427 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle);
418 // be making requests 428 }
419 if (!threadrunning) 429 } else if (itemtype == 7) // Service 7 (MAP_ITEM_LAND_FOR_SALE)
430 {
431 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle)
432 {
433 // Parcels
434 ILandChannel landChannel = m_scene.LandChannel;
435 List<ILandObject> parcels = landChannel.AllParcels();
436
437 // Local Map Item Request
438 List<mapItemReply> mapitems = new List<mapItemReply>();
439 mapItemReply mapitem = new mapItemReply();
440 if ((parcels != null) && (parcels.Count >= 1))
420 { 441 {
421 m_log.Warn("[WORLD MAP]: Starting new remote request thread manually. This means that AvatarEnteringParcel never fired! This needs to be fixed! Don't Mantis this, as the developers can see it in this message"); 442 foreach (ILandObject parcel_interface in parcels)
422 StartThread(new object()); 443 {
444 // Play it safe
445 if (!(parcel_interface is LandObject))
446 continue;
447
448 LandObject land = (LandObject)parcel_interface;
449 LandData parcel = land.LandData;
450
451 // Show land for sale
452 if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale)
453 {
454 Vector3 min = parcel.AABBMin;
455 Vector3 max = parcel.AABBMax;
456 float x = (min.X+max.X)/2;
457 float y = (min.Y+max.Y)/2;
458
459 mapitem = new mapItemReply();
460 mapitem.x = (uint)(xstart + x);
461 mapitem.y = (uint)(ystart + y);
462 // mapitem.z = (uint)m_scene.GetGroundHeight(x,y);
463 mapitem.id = UUID.Zero;
464 mapitem.name = parcel.Name;
465 mapitem.Extra = parcel.Area;
466 mapitem.Extra2 = parcel.SalePrice;
467 mapitems.Add(mapitem);
468 }
469 }
423 } 470 }
471 remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
472 }
473 else
474 {
475 // Remote Map Item Request
424 476
477 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes.
425 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); 478 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle);
426 } 479 }
427 } 480 }
@@ -542,6 +595,28 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
542 } 595 }
543 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); 596 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
544 } 597 }
598
599 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
600 uint itemtype = 7;
601
602 if (response.ContainsKey(itemtype.ToString()))
603 {
604 List<mapItemReply> returnitems = new List<mapItemReply>();
605 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
606 for (int i = 0; i < itemarray.Count; i++)
607 {
608 OSDMap mapitem = (OSDMap)itemarray[i];
609 mapItemReply mi = new mapItemReply();
610 mi.x = (uint)mapitem["X"].AsInteger();
611 mi.y = (uint)mapitem["Y"].AsInteger();
612 mi.id = mapitem["ID"].AsUUID();
613 mi.Extra = mapitem["Extra"].AsInteger();
614 mi.Extra2 = mapitem["Extra2"].AsInteger();
615 mi.name = mapitem["Name"].AsString();
616 returnitems.Add(mi);
617 }
618 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
619 }
545 } 620 }
546 } 621 }
547 } 622 }
@@ -589,12 +664,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
589 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 664 private OSDMap RequestMapItemsAsync(UUID id, uint flags,
590 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 665 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
591 { 666 {
667// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
668
592 string httpserver = ""; 669 string httpserver = "";
593 bool blacklisted = false; 670 bool blacklisted = false;
594 lock (m_blacklistedregions) 671 lock (m_blacklistedregions)
595 { 672 {
596 if (m_blacklistedregions.ContainsKey(regionhandle)) 673 if (m_blacklistedregions.ContainsKey(regionhandle))
597 blacklisted = true; 674 {
675 if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout))
676 {
677 m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted region {0}", regionhandle);
678
679 m_blacklistedregions.Remove(regionhandle);
680 }
681 else
682 blacklisted = true;
683 }
598 } 684 }
599 685
600 if (blacklisted) 686 if (blacklisted)
@@ -636,7 +722,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
636 lock (m_blacklistedurls) 722 lock (m_blacklistedurls)
637 { 723 {
638 if (m_blacklistedurls.ContainsKey(httpserver)) 724 if (m_blacklistedurls.ContainsKey(httpserver))
639 blacklisted = true; 725 {
726 if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout))
727 {
728 m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted URL {0}", httpserver);
729
730 m_blacklistedurls.Remove(httpserver);
731 }
732 else
733 blacklisted = true;
734 }
640 } 735 }
641 736
642 // Can't find the http server 737 // Can't find the http server
@@ -682,7 +777,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
682 mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send 777 mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send
683 os = mapitemsrequest.GetRequestStream(); 778 os = mapitemsrequest.GetRequestStream();
684 os.Write(buffer, 0, buffer.Length); //Send it 779 os.Write(buffer, 0, buffer.Length); //Send it
685 os.Close();
686 //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver); 780 //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver);
687 } 781 }
688 catch (WebException ex) 782 catch (WebException ex)
@@ -705,6 +799,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
705 responseMap["connect"] = OSD.FromBoolean(false); 799 responseMap["connect"] = OSD.FromBoolean(false);
706 return responseMap; 800 return responseMap;
707 } 801 }
802 finally
803 {
804 if (os != null)
805 os.Close();
806 }
708 807
709 string response_mapItems_reply = null; 808 string response_mapItems_reply = null;
710 { // get the response 809 { // get the response
@@ -1060,6 +1159,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1060 1159
1061 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); 1160 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart);
1062 1161
1162 // Service 6 (MAP_ITEM_AGENTS_LOCATION; green dots)
1163
1063 OSDMap responsemap = new OSDMap(); 1164 OSDMap responsemap = new OSDMap();
1064 int tc = Environment.TickCount; 1165 int tc = Environment.TickCount;
1065 if (m_scene.GetRootAgentCount() == 0) 1166 if (m_scene.GetRootAgentCount() == 0)
@@ -1092,6 +1193,60 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1092 }); 1193 });
1093 responsemap["6"] = responsearr; 1194 responsemap["6"] = responsearr;
1094 } 1195 }
1196
1197 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
1198
1199 ILandChannel landChannel = m_scene.LandChannel;
1200 List<ILandObject> parcels = landChannel.AllParcels();
1201
1202 if ((parcels == null) || (parcels.Count == 0))
1203 {
1204 OSDMap responsemapdata = new OSDMap();
1205 responsemapdata["X"] = OSD.FromInteger((int)(xstart + 1));
1206 responsemapdata["Y"] = OSD.FromInteger((int)(ystart + 1));
1207 responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
1208 responsemapdata["Name"] = OSD.FromString("");
1209 responsemapdata["Extra"] = OSD.FromInteger(0);
1210 responsemapdata["Extra2"] = OSD.FromInteger(0);
1211 OSDArray responsearr = new OSDArray();
1212 responsearr.Add(responsemapdata);
1213
1214 responsemap["7"] = responsearr;
1215 }
1216 else
1217 {
1218 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount());
1219 foreach (ILandObject parcel_interface in parcels)
1220 {
1221 // Play it safe
1222 if (!(parcel_interface is LandObject))
1223 continue;
1224
1225 LandObject land = (LandObject)parcel_interface;
1226 LandData parcel = land.LandData;
1227
1228 // Show land for sale
1229 if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale)
1230 {
1231 Vector3 min = parcel.AABBMin;
1232 Vector3 max = parcel.AABBMax;
1233 float x = (min.X+max.X)/2;
1234 float y = (min.Y+max.Y)/2;
1235
1236 OSDMap responsemapdata = new OSDMap();
1237 responsemapdata["X"] = OSD.FromInteger((int)(xstart + x));
1238 responsemapdata["Y"] = OSD.FromInteger((int)(ystart + y));
1239 // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y));
1240 responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
1241 responsemapdata["Name"] = OSD.FromString(parcel.Name);
1242 responsemapdata["Extra"] = OSD.FromInteger(parcel.Area);
1243 responsemapdata["Extra2"] = OSD.FromInteger(parcel.SalePrice);
1244 responsearr.Add(responsemapdata);
1245 }
1246 }
1247 responsemap["7"] = responsearr;
1248 }
1249
1095 return responsemap; 1250 return responsemap;
1096 } 1251 }
1097 1252
@@ -1110,14 +1265,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1110 if (data == null) 1265 if (data == null)
1111 return; 1266 return;
1112 1267
1113 UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID;
1114
1115 m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); 1268 m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE");
1116 1269
1117 m_scene.RegionInfo.RegionSettings.TerrainImageID = UUID.Random(); 1270 UUID terrainImageID = UUID.Random();
1118 1271
1119 AssetBase asset = new AssetBase( 1272 AssetBase asset = new AssetBase(
1120 m_scene.RegionInfo.RegionSettings.TerrainImageID, 1273 terrainImageID,
1121 "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(), 1274 "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(),
1122 (sbyte)AssetType.Texture, 1275 (sbyte)AssetType.Texture,
1123 m_scene.RegionInfo.RegionID.ToString()); 1276 m_scene.RegionInfo.RegionID.ToString());
@@ -1129,6 +1282,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1129 // Store the new one 1282 // Store the new one
1130 m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); 1283 m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID);
1131 m_scene.AssetService.Store(asset); 1284 m_scene.AssetService.Store(asset);
1285
1286 // Switch to the new one
1287 UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID;
1288 m_scene.RegionInfo.RegionSettings.TerrainImageID = terrainImageID;
1132 m_scene.RegionInfo.RegionSettings.Save(); 1289 m_scene.RegionInfo.RegionSettings.Save();
1133 1290
1134 // Delete the old one 1291 // Delete the old one
@@ -1138,12 +1295,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1138 1295
1139 private void MakeRootAgent(ScenePresence avatar) 1296 private void MakeRootAgent(ScenePresence avatar)
1140 { 1297 {
1141 // You may ask, why this is in a threadpool to start with..
1142 // The reason is so we don't cause the thread to freeze waiting
1143 // for the 1 second it costs to start a thread manually.
1144 if (!threadrunning)
1145 Util.FireAndForget(this.StartThread);
1146
1147 lock (m_rootAgents) 1298 lock (m_rootAgents)
1148 { 1299 {
1149 if (!m_rootAgents.Contains(avatar.UUID)) 1300 if (!m_rootAgents.Contains(avatar.UUID))
@@ -1158,8 +1309,30 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1158 lock (m_rootAgents) 1309 lock (m_rootAgents)
1159 { 1310 {
1160 m_rootAgents.Remove(avatar.UUID); 1311 m_rootAgents.Remove(avatar.UUID);
1161 if (m_rootAgents.Count == 0) 1312 }
1162 StopThread(); 1313 }
1314
1315 public void OnRegionUp(GridRegion otherRegion)
1316 {
1317 ulong regionhandle = otherRegion.RegionHandle;
1318 string httpserver = otherRegion.ServerURI + "MAP/MapItems/" + regionhandle.ToString();
1319
1320 lock (m_blacklistedregions)
1321 {
1322 if (!m_blacklistedregions.ContainsKey(regionhandle))
1323 m_blacklistedregions.Remove(regionhandle);
1324 }
1325
1326 lock (m_blacklistedurls)
1327 {
1328 if (m_blacklistedurls.ContainsKey(httpserver))
1329 m_blacklistedurls.Remove(httpserver);
1330 }
1331
1332 lock (m_cachedRegionMapItemsAddress)
1333 {
1334 if (!m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
1335 m_cachedRegionMapItemsAddress.Remove(regionhandle);
1163 } 1336 }
1164 } 1337 }
1165 1338