aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs206
1 files changed, 187 insertions, 19 deletions
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 7b00597..710230a 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,58 @@ 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 int tc = Environment.TickCount;
439 List<mapItemReply> mapitems = new List<mapItemReply>();
440 mapItemReply mapitem = new mapItemReply();
441 if ((parcels != null) && (parcels.Count >= 1))
420 { 442 {
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"); 443 foreach (ILandObject parcel_interface in parcels)
422 StartThread(new object()); 444 {
445 // Play it safe
446 if (!(parcel_interface is LandObject))
447 continue;
448
449 LandObject land = (LandObject)parcel_interface;
450 LandData parcel = land.LandData;
451
452 // Show land for sale
453 if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale)
454 {
455 Vector3 min = parcel.AABBMin;
456 Vector3 max = parcel.AABBMax;
457 float x = (min.X+max.X)/2;
458 float y = (min.Y+max.Y)/2;
459
460 mapitem = new mapItemReply();
461 mapitem.x = (uint)(xstart + x);
462 mapitem.y = (uint)(ystart + y);
463 // mapitem.z = (uint)m_scene.GetGroundHeight(x,y);
464 mapitem.id = UUID.Zero;
465 mapitem.name = parcel.Name;
466 mapitem.Extra = parcel.Area;
467 mapitem.Extra2 = parcel.SalePrice;
468 mapitems.Add(mapitem);
469 }
470 }
423 } 471 }
472 remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
473 }
474 else
475 {
476 // Remote Map Item Request
424 477
478 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes.
425 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); 479 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle);
426 } 480 }
427 } 481 }
@@ -542,6 +596,28 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
542 } 596 }
543 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); 597 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
544 } 598 }
599
600 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
601 uint itemtype = 7;
602
603 if (response.ContainsKey(itemtype.ToString()))
604 {
605 List<mapItemReply> returnitems = new List<mapItemReply>();
606 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
607 for (int i = 0; i < itemarray.Count; i++)
608 {
609 OSDMap mapitem = (OSDMap)itemarray[i];
610 mapItemReply mi = new mapItemReply();
611 mi.x = (uint)mapitem["X"].AsInteger();
612 mi.y = (uint)mapitem["Y"].AsInteger();
613 mi.id = mapitem["ID"].AsUUID();
614 mi.Extra = mapitem["Extra"].AsInteger();
615 mi.Extra2 = mapitem["Extra2"].AsInteger();
616 mi.name = mapitem["Name"].AsString();
617 returnitems.Add(mi);
618 }
619 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
620 }
545 } 621 }
546 } 622 }
547 } 623 }
@@ -589,12 +665,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
589 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 665 private OSDMap RequestMapItemsAsync(UUID id, uint flags,
590 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 666 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
591 { 667 {
668// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
669
592 string httpserver = ""; 670 string httpserver = "";
593 bool blacklisted = false; 671 bool blacklisted = false;
594 lock (m_blacklistedregions) 672 lock (m_blacklistedregions)
595 { 673 {
596 if (m_blacklistedregions.ContainsKey(regionhandle)) 674 if (m_blacklistedregions.ContainsKey(regionhandle))
597 blacklisted = true; 675 {
676 if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout))
677 {
678 m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted region {0}", regionhandle);
679
680 m_blacklistedregions.Remove(regionhandle);
681 }
682 else
683 blacklisted = true;
684 }
598 } 685 }
599 686
600 if (blacklisted) 687 if (blacklisted)
@@ -636,7 +723,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
636 lock (m_blacklistedurls) 723 lock (m_blacklistedurls)
637 { 724 {
638 if (m_blacklistedurls.ContainsKey(httpserver)) 725 if (m_blacklistedurls.ContainsKey(httpserver))
639 blacklisted = true; 726 {
727 if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout))
728 {
729 m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted URL {0}", httpserver);
730
731 m_blacklistedurls.Remove(httpserver);
732 }
733 else
734 blacklisted = true;
735 }
640 } 736 }
641 737
642 // Can't find the http server 738 // Can't find the http server
@@ -1064,6 +1160,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1064 1160
1065 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); 1161 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart);
1066 1162
1163 // Service 6 (MAP_ITEM_AGENTS_LOCATION; green dots)
1164
1067 OSDMap responsemap = new OSDMap(); 1165 OSDMap responsemap = new OSDMap();
1068 int tc = Environment.TickCount; 1166 int tc = Environment.TickCount;
1069 if (m_scene.GetRootAgentCount() == 0) 1167 if (m_scene.GetRootAgentCount() == 0)
@@ -1096,6 +1194,60 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1096 }); 1194 });
1097 responsemap["6"] = responsearr; 1195 responsemap["6"] = responsearr;
1098 } 1196 }
1197
1198 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
1199
1200 ILandChannel landChannel = m_scene.LandChannel;
1201 List<ILandObject> parcels = landChannel.AllParcels();
1202
1203 if ((parcels == null) || (parcels.Count == 0))
1204 {
1205 OSDMap responsemapdata = new OSDMap();
1206 responsemapdata["X"] = OSD.FromInteger((int)(xstart + 1));
1207 responsemapdata["Y"] = OSD.FromInteger((int)(ystart + 1));
1208 responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
1209 responsemapdata["Name"] = OSD.FromString("");
1210 responsemapdata["Extra"] = OSD.FromInteger(0);
1211 responsemapdata["Extra2"] = OSD.FromInteger(0);
1212 OSDArray responsearr = new OSDArray();
1213 responsearr.Add(responsemapdata);
1214
1215 responsemap["7"] = responsearr;
1216 }
1217 else
1218 {
1219 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount());
1220 foreach (ILandObject parcel_interface in parcels)
1221 {
1222 // Play it safe
1223 if (!(parcel_interface is LandObject))
1224 continue;
1225
1226 LandObject land = (LandObject)parcel_interface;
1227 LandData parcel = land.LandData;
1228
1229 // Show land for sale
1230 if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale)
1231 {
1232 Vector3 min = parcel.AABBMin;
1233 Vector3 max = parcel.AABBMax;
1234 float x = (min.X+max.X)/2;
1235 float y = (min.Y+max.Y)/2;
1236
1237 OSDMap responsemapdata = new OSDMap();
1238 responsemapdata["X"] = OSD.FromInteger((int)(xstart + x));
1239 responsemapdata["Y"] = OSD.FromInteger((int)(ystart + y));
1240 // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y));
1241 responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
1242 responsemapdata["Name"] = OSD.FromString(parcel.Name);
1243 responsemapdata["Extra"] = OSD.FromInteger(parcel.Area);
1244 responsemapdata["Extra2"] = OSD.FromInteger(parcel.SalePrice);
1245 responsearr.Add(responsemapdata);
1246 }
1247 }
1248 responsemap["7"] = responsearr;
1249 }
1250
1099 return responsemap; 1251 return responsemap;
1100 } 1252 }
1101 1253
@@ -1144,12 +1296,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1144 1296
1145 private void MakeRootAgent(ScenePresence avatar) 1297 private void MakeRootAgent(ScenePresence avatar)
1146 { 1298 {
1147 // You may ask, why this is in a threadpool to start with..
1148 // The reason is so we don't cause the thread to freeze waiting
1149 // for the 1 second it costs to start a thread manually.
1150 if (!threadrunning)
1151 Util.FireAndForget(this.StartThread);
1152
1153 lock (m_rootAgents) 1299 lock (m_rootAgents)
1154 { 1300 {
1155 if (!m_rootAgents.Contains(avatar.UUID)) 1301 if (!m_rootAgents.Contains(avatar.UUID))
@@ -1164,8 +1310,30 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1164 lock (m_rootAgents) 1310 lock (m_rootAgents)
1165 { 1311 {
1166 m_rootAgents.Remove(avatar.UUID); 1312 m_rootAgents.Remove(avatar.UUID);
1167 if (m_rootAgents.Count == 0) 1313 }
1168 StopThread(); 1314 }
1315
1316 public void OnRegionUp(GridRegion otherRegion)
1317 {
1318 ulong regionhandle = otherRegion.RegionHandle;
1319 string httpserver = otherRegion.ServerURI + "MAP/MapItems/" + regionhandle.ToString();
1320
1321 lock (m_blacklistedregions)
1322 {
1323 if (!m_blacklistedregions.ContainsKey(regionhandle))
1324 m_blacklistedregions.Remove(regionhandle);
1325 }
1326
1327 lock (m_blacklistedurls)
1328 {
1329 if (m_blacklistedurls.ContainsKey(httpserver))
1330 m_blacklistedurls.Remove(httpserver);
1331 }
1332
1333 lock (m_cachedRegionMapItemsAddress)
1334 {
1335 if (!m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
1336 m_cachedRegionMapItemsAddress.Remove(regionhandle);
1169 } 1337 }
1170 } 1338 }
1171 1339