diff options
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 206 |
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; | |||
46 | using OpenSim.Framework.Servers.HttpServer; | 46 | using OpenSim.Framework.Servers.HttpServer; |
47 | using OpenSim.Region.Framework.Interfaces; | 47 | using OpenSim.Region.Framework.Interfaces; |
48 | using OpenSim.Region.Framework.Scenes; | 48 | using OpenSim.Region.Framework.Scenes; |
49 | using OpenSim.Region.CoreModules.World.Land; | ||
49 | using Caps=OpenSim.Framework.Capabilities.Caps; | 50 | using Caps=OpenSim.Framework.Capabilities.Caps; |
50 | using OSDArray=OpenMetaverse.StructuredData.OSDArray; | 51 | using OSDArray=OpenMetaverse.StructuredData.OSDArray; |
51 | using OSDMap=OpenMetaverse.StructuredData.OSDMap; | 52 | using 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 | ||