diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 517 |
1 files changed, 334 insertions, 183 deletions
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index e2f525c..db1187e 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -59,13 +59,18 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
59 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WorldMapModule")] | 59 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WorldMapModule")] |
60 | public class WorldMapModule : INonSharedRegionModule, IWorldMapModule | 60 | public class WorldMapModule : INonSharedRegionModule, IWorldMapModule |
61 | { | 61 | { |
62 | private static readonly ILog m_log = | 62 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
63 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 63 | #pragma warning disable 414 |
64 | private static string LogHeader = "[WORLD MAP]"; | ||
65 | #pragma warning restore 414 | ||
64 | 66 | ||
65 | private static readonly string DEFAULT_WORLD_MAP_EXPORT_PATH = "exportmap.jpg"; | 67 | private static readonly string DEFAULT_WORLD_MAP_EXPORT_PATH = "exportmap.jpg"; |
66 | private static readonly UUID STOP_UUID = UUID.Random(); | 68 | private static readonly UUID STOP_UUID = UUID.Random(); |
67 | private static readonly string m_mapLayerPath = "0001/"; | 69 | private static readonly string m_mapLayerPath = "0001/"; |
68 | 70 | ||
71 | private IMapImageGenerator m_mapImageGenerator; | ||
72 | private IMapImageUploadModule m_mapImageServiceModule; | ||
73 | |||
69 | private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>(); | 74 | private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>(); |
70 | 75 | ||
71 | protected Scene m_scene; | 76 | protected Scene m_scene; |
@@ -81,19 +86,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
81 | private List<UUID> m_rootAgents = new List<UUID>(); | 86 | private List<UUID> m_rootAgents = new List<UUID>(); |
82 | private volatile bool threadrunning = false; | 87 | private volatile bool threadrunning = false; |
83 | 88 | ||
89 | private IServiceThrottleModule m_ServiceThrottle; | ||
90 | |||
84 | //private int CacheRegionsDistance = 256; | 91 | //private int CacheRegionsDistance = 256; |
85 | 92 | ||
86 | #region INonSharedRegionModule Members | 93 | #region INonSharedRegionModule Members |
87 | public virtual void Initialise (IConfigSource config) | 94 | public virtual void Initialise (IConfigSource config) |
88 | { | 95 | { |
89 | IConfig startupConfig = config.Configs["Startup"]; | 96 | string[] configSections = new string[] { "Map", "Startup" }; |
90 | if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap") | 97 | |
98 | if (Util.GetConfigVarFromSections<string>( | ||
99 | config, "WorldMapModule", configSections, "WorldMap") == "WorldMap") | ||
91 | m_Enabled = true; | 100 | m_Enabled = true; |
92 | 101 | ||
93 | blacklistTimeout = startupConfig.GetInt("BlacklistTimeout", 10*60) * 1000; | 102 | blacklistTimeout |
103 | = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000; | ||
94 | } | 104 | } |
95 | 105 | ||
96 | public virtual void AddRegion (Scene scene) | 106 | public virtual void AddRegion(Scene scene) |
97 | { | 107 | { |
98 | if (!m_Enabled) | 108 | if (!m_Enabled) |
99 | return; | 109 | return; |
@@ -109,6 +119,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
109 | "export-map [<path>]", | 119 | "export-map [<path>]", |
110 | "Save an image of the world map", HandleExportWorldMapConsoleCommand); | 120 | "Save an image of the world map", HandleExportWorldMapConsoleCommand); |
111 | 121 | ||
122 | m_scene.AddCommand( | ||
123 | "Regions", this, "generate map", | ||
124 | "generate map", | ||
125 | "Generates and stores a new maptile.", HandleGenerateMapConsoleCommand); | ||
126 | |||
112 | AddHandlers(); | 127 | AddHandlers(); |
113 | } | 128 | } |
114 | } | 129 | } |
@@ -128,8 +143,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
128 | 143 | ||
129 | public virtual void RegionLoaded (Scene scene) | 144 | public virtual void RegionLoaded (Scene scene) |
130 | { | 145 | { |
131 | } | 146 | if (!m_Enabled) |
147 | return; | ||
132 | 148 | ||
149 | m_ServiceThrottle = scene.RequestModuleInterface<IServiceThrottleModule>(); | ||
150 | |||
151 | m_mapImageGenerator = m_scene.RequestModuleInterface<IMapImageGenerator>(); | ||
152 | m_mapImageServiceModule = m_scene.RequestModuleInterface<IMapImageUploadModule>(); | ||
153 | } | ||
133 | 154 | ||
134 | public virtual void Close() | 155 | public virtual void Close() |
135 | { | 156 | { |
@@ -156,7 +177,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
156 | regionimage = regionimage.Replace("-", ""); | 177 | regionimage = regionimage.Replace("-", ""); |
157 | m_log.Info("[WORLD MAP]: JPEG Map location: " + m_scene.RegionInfo.ServerURI + "index.php?method=" + regionimage); | 178 | m_log.Info("[WORLD MAP]: JPEG Map location: " + m_scene.RegionInfo.ServerURI + "index.php?method=" + regionimage); |
158 | 179 | ||
159 | MainServer.Instance.AddHTTPHandler(regionimage, OnHTTPGetMapImage); | 180 | MainServer.Instance.AddHTTPHandler(regionimage, |
181 | new GenericHTTPDOSProtector(OnHTTPGetMapImage, OnHTTPThrottled, new BasicDosProtectorOptions() | ||
182 | { | ||
183 | AllowXForwardedFor = false, | ||
184 | ForgetTimeSpan = TimeSpan.FromMinutes(2), | ||
185 | MaxRequestsInTimeframe = 4, | ||
186 | ReportingName = "MAPDOSPROTECTOR", | ||
187 | RequestTimeSpan = TimeSpan.FromSeconds(10), | ||
188 | ThrottledAction = BasicDOSProtector.ThrottleAction.DoThrottledMethod | ||
189 | }).Process); | ||
160 | MainServer.Instance.AddLLSDHandler( | 190 | MainServer.Instance.AddLLSDHandler( |
161 | "/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), HandleRemoteMapItemRequest); | 191 | "/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), HandleRemoteMapItemRequest); |
162 | 192 | ||
@@ -167,13 +197,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
167 | m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; | 197 | m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; |
168 | m_scene.EventManager.OnRegionUp += OnRegionUp; | 198 | m_scene.EventManager.OnRegionUp += OnRegionUp; |
169 | 199 | ||
170 | StartThread(new object()); | 200 | // StartThread(new object()); |
171 | } | 201 | } |
172 | 202 | ||
173 | // this has to be called with a lock on m_scene | 203 | // this has to be called with a lock on m_scene |
174 | protected virtual void RemoveHandlers() | 204 | protected virtual void RemoveHandlers() |
175 | { | 205 | { |
176 | StopThread(); | 206 | // StopThread(); |
177 | 207 | ||
178 | m_scene.EventManager.OnRegionUp -= OnRegionUp; | 208 | m_scene.EventManager.OnRegionUp -= OnRegionUp; |
179 | m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; | 209 | m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; |
@@ -259,15 +289,15 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
259 | { | 289 | { |
260 | List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; | 290 | List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; |
261 | 291 | ||
292 | // Get regions that are within 8 regions of here | ||
262 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, | 293 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, |
263 | (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, | 294 | (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocX - 8), |
264 | (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, | 295 | (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocX + 8), |
265 | (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, | 296 | (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocY - 8), |
266 | (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); | 297 | (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocY + 8) ); |
267 | foreach (GridRegion r in regions) | 298 | foreach (GridRegion r in regions) |
268 | { | 299 | { |
269 | MapBlockData block = new MapBlockData(); | 300 | MapBlockData block = MapBlockFromGridRegion(r, 0); |
270 | MapBlockFromGridRegion(block, r, 0); | ||
271 | mapBlocks.Add(block); | 301 | mapBlocks.Add(block); |
272 | } | 302 | } |
273 | avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); | 303 | avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); |
@@ -351,7 +381,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
351 | 381 | ||
352 | // m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread"); | 382 | // m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread"); |
353 | 383 | ||
354 | Watchdog.StartThread( | 384 | WorkManager.StartThread( |
355 | process, | 385 | process, |
356 | string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName), | 386 | string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName), |
357 | ThreadPriority.BelowNormal, | 387 | ThreadPriority.BelowNormal, |
@@ -387,24 +417,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
387 | } | 417 | } |
388 | uint xstart = 0; | 418 | uint xstart = 0; |
389 | uint ystart = 0; | 419 | uint ystart = 0; |
390 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out xstart, out ystart); | 420 | Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out xstart, out ystart); |
391 | if (itemtype == 6) // Service 6 right now (MAP_ITEM_AGENTS_LOCATION; green dots) | 421 | if (itemtype == (int)GridItemType.AgentLocations) |
392 | { | 422 | { |
393 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) | 423 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) |
394 | { | 424 | { |
395 | // Local Map Item Request | 425 | // Just requesting map info about the current, local region |
396 | int tc = Environment.TickCount; | 426 | int tc = Environment.TickCount; |
397 | List<mapItemReply> mapitems = new List<mapItemReply>(); | 427 | List<mapItemReply> mapitems = new List<mapItemReply>(); |
398 | mapItemReply mapitem = new mapItemReply(); | 428 | mapItemReply mapitem = new mapItemReply(); |
399 | if (m_scene.GetRootAgentCount() <= 1) | 429 | if (m_scene.GetRootAgentCount() <= 1) |
400 | { | 430 | { |
401 | mapitem = new mapItemReply(); | 431 | mapitem = new mapItemReply( |
402 | mapitem.x = (uint)(xstart + 1); | 432 | xstart + 1, |
403 | mapitem.y = (uint)(ystart + 1); | 433 | ystart + 1, |
404 | mapitem.id = UUID.Zero; | 434 | UUID.Zero, |
405 | mapitem.name = Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()); | 435 | Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()), |
406 | mapitem.Extra = 0; | 436 | 0, 0); |
407 | mapitem.Extra2 = 0; | ||
408 | mapitems.Add(mapitem); | 437 | mapitems.Add(mapitem); |
409 | } | 438 | } |
410 | else | 439 | else |
@@ -414,13 +443,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
414 | // Don't send a green dot for yourself | 443 | // Don't send a green dot for yourself |
415 | if (sp.UUID != remoteClient.AgentId) | 444 | if (sp.UUID != remoteClient.AgentId) |
416 | { | 445 | { |
417 | mapitem = new mapItemReply(); | 446 | mapitem = new mapItemReply( |
418 | mapitem.x = (uint)(xstart + sp.AbsolutePosition.X); | 447 | xstart + (uint)sp.AbsolutePosition.X, |
419 | mapitem.y = (uint)(ystart + sp.AbsolutePosition.Y); | 448 | ystart + (uint)sp.AbsolutePosition.Y, |
420 | mapitem.id = UUID.Zero; | 449 | UUID.Zero, |
421 | mapitem.name = Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()); | 450 | Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()), |
422 | mapitem.Extra = 1; | 451 | 1, 0); |
423 | mapitem.Extra2 = 0; | ||
424 | mapitems.Add(mapitem); | 452 | mapitems.Add(mapitem); |
425 | } | 453 | } |
426 | }); | 454 | }); |
@@ -435,7 +463,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
435 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); | 463 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); |
436 | } | 464 | } |
437 | } | 465 | } |
438 | else if (itemtype == 7) // Service 7 (MAP_ITEM_LAND_FOR_SALE) | 466 | else if (itemtype == (int)GridItemType.LandForSale) // Service 7 (MAP_ITEM_LAND_FOR_SALE) |
439 | { | 467 | { |
440 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) | 468 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) |
441 | { | 469 | { |
@@ -465,14 +493,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
465 | float x = (min.X+max.X)/2; | 493 | float x = (min.X+max.X)/2; |
466 | float y = (min.Y+max.Y)/2; | 494 | float y = (min.Y+max.Y)/2; |
467 | 495 | ||
468 | mapitem = new mapItemReply(); | 496 | mapitem = new mapItemReply( |
469 | mapitem.x = (uint)(xstart + x); | 497 | xstart + (uint)x, |
470 | mapitem.y = (uint)(ystart + y); | 498 | ystart + (uint)y, |
471 | // mapitem.z = (uint)m_scene.GetGroundHeight(x,y); | 499 | parcel.GlobalID, |
472 | mapitem.id = parcel.GlobalID; | 500 | parcel.Name, |
473 | mapitem.name = parcel.Name; | 501 | parcel.Area, |
474 | mapitem.Extra = parcel.Area; | 502 | parcel.SalePrice |
475 | mapitem.Extra2 = parcel.SalePrice; | 503 | ); |
476 | mapitems.Add(mapitem); | 504 | mapitems.Add(mapitem); |
477 | } | 505 | } |
478 | } | 506 | } |
@@ -487,7 +515,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
487 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); | 515 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); |
488 | } | 516 | } |
489 | } | 517 | } |
490 | else if (itemtype == 1) // Service 1 (MAP_ITEM_TELEHUB) | 518 | else if (itemtype == (int)GridItemType.Telehub) // Service 1 (MAP_ITEM_TELEHUB) |
491 | { | 519 | { |
492 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) | 520 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) |
493 | { | 521 | { |
@@ -497,13 +525,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
497 | SceneObjectGroup sog = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject); | 525 | SceneObjectGroup sog = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject); |
498 | if (sog != null) | 526 | if (sog != null) |
499 | { | 527 | { |
500 | mapitem = new mapItemReply(); | 528 | mapitem = new mapItemReply( |
501 | mapitem.x = (uint)(xstart + sog.AbsolutePosition.X); | 529 | xstart + (uint)sog.AbsolutePosition.X, |
502 | mapitem.y = (uint)(ystart + sog.AbsolutePosition.Y); | 530 | ystart + (uint)sog.AbsolutePosition.Y, |
503 | mapitem.id = UUID.Zero; | 531 | UUID.Zero, |
504 | mapitem.name = sog.Name; | 532 | sog.Name, |
505 | mapitem.Extra = 0; // color (not used) | 533 | 0, // color (not used) |
506 | mapitem.Extra2 = 0; // 0 = telehub / 1 = infohub | 534 | 0 // 0 = telehub / 1 = infohub |
535 | ); | ||
507 | mapitems.Add(mapitem); | 536 | mapitems.Add(mapitem); |
508 | 537 | ||
509 | remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); | 538 | remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); |
@@ -523,7 +552,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
523 | /// </summary> | 552 | /// </summary> |
524 | public void process() | 553 | public void process() |
525 | { | 554 | { |
526 | const int MAX_ASYNC_REQUESTS = 20; | 555 | //const int MAX_ASYNC_REQUESTS = 20; |
527 | try | 556 | try |
528 | { | 557 | { |
529 | while (true) | 558 | while (true) |
@@ -568,13 +597,44 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
568 | Watchdog.RemoveThread(); | 597 | Watchdog.RemoveThread(); |
569 | } | 598 | } |
570 | 599 | ||
600 | const int MAX_ASYNC_REQUESTS = 20; | ||
601 | |||
571 | /// <summary> | 602 | /// <summary> |
572 | /// Enqueues the map item request into the processing thread | 603 | /// Enqueues the map item request into the services throttle processing thread |
573 | /// </summary> | 604 | /// </summary> |
574 | /// <param name="state"></param> | 605 | /// <param name="state"></param> |
575 | public void EnqueueMapItemRequest(MapRequestState state) | 606 | public void EnqueueMapItemRequest(MapRequestState st) |
576 | { | 607 | { |
577 | requests.Enqueue(state); | 608 | |
609 | m_ServiceThrottle.Enqueue("map-item", st.regionhandle.ToString() + st.agentID.ToString(), delegate | ||
610 | { | ||
611 | if (st.agentID != UUID.Zero) | ||
612 | { | ||
613 | bool dorequest = true; | ||
614 | lock (m_rootAgents) | ||
615 | { | ||
616 | if (!m_rootAgents.Contains(st.agentID)) | ||
617 | dorequest = false; | ||
618 | } | ||
619 | |||
620 | if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) | ||
621 | { | ||
622 | if (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break | ||
623 | { | ||
624 | // AH!!! Recursive ! | ||
625 | // Put this request back in the queue and return | ||
626 | EnqueueMapItemRequest(st); | ||
627 | return; | ||
628 | } | ||
629 | |||
630 | RequestMapItemsDelegate d = RequestMapItemsAsync; | ||
631 | d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null); | ||
632 | //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); | ||
633 | //RequestMapItemsCompleted(response); | ||
634 | Interlocked.Increment(ref nAsyncRequests); | ||
635 | } | ||
636 | } | ||
637 | }); | ||
578 | } | 638 | } |
579 | 639 | ||
580 | /// <summary> | 640 | /// <summary> |
@@ -622,19 +682,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
622 | { | 682 | { |
623 | OSDMap mapitem = (OSDMap)itemarray[i]; | 683 | OSDMap mapitem = (OSDMap)itemarray[i]; |
624 | mapItemReply mi = new mapItemReply(); | 684 | mapItemReply mi = new mapItemReply(); |
625 | mi.x = (uint)mapitem["X"].AsInteger(); | 685 | mi.FromOSD(mapitem); |
626 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
627 | mi.id = mapitem["ID"].AsUUID(); | ||
628 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
629 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
630 | mi.name = mapitem["Name"].AsString(); | ||
631 | returnitems.Add(mi); | 686 | returnitems.Add(mi); |
632 | } | 687 | } |
633 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); | 688 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); |
634 | } | 689 | } |
635 | 690 | ||
636 | // Service 7 (MAP_ITEM_LAND_FOR_SALE) | 691 | // Service 7 (MAP_ITEM_LAND_FOR_SALE) |
637 | uint itemtype = 7; | 692 | uint itemtype = (uint)GridItemType.LandForSale; |
638 | 693 | ||
639 | if (response.ContainsKey(itemtype.ToString())) | 694 | if (response.ContainsKey(itemtype.ToString())) |
640 | { | 695 | { |
@@ -644,19 +699,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
644 | { | 699 | { |
645 | OSDMap mapitem = (OSDMap)itemarray[i]; | 700 | OSDMap mapitem = (OSDMap)itemarray[i]; |
646 | mapItemReply mi = new mapItemReply(); | 701 | mapItemReply mi = new mapItemReply(); |
647 | mi.x = (uint)mapitem["X"].AsInteger(); | 702 | mi.FromOSD(mapitem); |
648 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
649 | mi.id = mapitem["ID"].AsUUID(); | ||
650 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
651 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
652 | mi.name = mapitem["Name"].AsString(); | ||
653 | returnitems.Add(mi); | 703 | returnitems.Add(mi); |
654 | } | 704 | } |
655 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); | 705 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); |
656 | } | 706 | } |
657 | 707 | ||
658 | // Service 1 (MAP_ITEM_TELEHUB) | 708 | // Service 1 (MAP_ITEM_TELEHUB) |
659 | itemtype = 1; | 709 | itemtype = (uint)GridItemType.Telehub; |
660 | 710 | ||
661 | if (response.ContainsKey(itemtype.ToString())) | 711 | if (response.ContainsKey(itemtype.ToString())) |
662 | { | 712 | { |
@@ -666,12 +716,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
666 | { | 716 | { |
667 | OSDMap mapitem = (OSDMap)itemarray[i]; | 717 | OSDMap mapitem = (OSDMap)itemarray[i]; |
668 | mapItemReply mi = new mapItemReply(); | 718 | mapItemReply mi = new mapItemReply(); |
669 | mi.x = (uint)mapitem["X"].AsInteger(); | 719 | mi.FromOSD(mapitem); |
670 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
671 | mi.id = mapitem["ID"].AsUUID(); | ||
672 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
673 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
674 | mi.name = mapitem["Name"].AsString(); | ||
675 | returnitems.Add(mi); | 720 | returnitems.Add(mi); |
676 | } | 721 | } |
677 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); | 722 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); |
@@ -754,7 +799,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
754 | if (httpserver.Length == 0) | 799 | if (httpserver.Length == 0) |
755 | { | 800 | { |
756 | uint x = 0, y = 0; | 801 | uint x = 0, y = 0; |
757 | Utils.LongToUInts(regionhandle, out x, out y); | 802 | Util.RegionHandleToWorldLoc(regionhandle, out x, out y); |
758 | GridRegion mreg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); | 803 | GridRegion mreg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); |
759 | 804 | ||
760 | if (mreg != null) | 805 | if (mreg != null) |
@@ -861,24 +906,26 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
861 | finally | 906 | finally |
862 | { | 907 | { |
863 | if (os != null) | 908 | if (os != null) |
864 | os.Close(); | 909 | os.Dispose(); |
865 | } | 910 | } |
866 | 911 | ||
867 | string response_mapItems_reply = null; | 912 | string response_mapItems_reply = null; |
868 | { // get the response | 913 | { |
869 | StreamReader sr = null; | ||
870 | try | 914 | try |
871 | { | 915 | { |
872 | WebResponse webResponse = mapitemsrequest.GetResponse(); | 916 | using (WebResponse webResponse = mapitemsrequest.GetResponse()) |
873 | if (webResponse != null) | ||
874 | { | ||
875 | sr = new StreamReader(webResponse.GetResponseStream()); | ||
876 | response_mapItems_reply = sr.ReadToEnd().Trim(); | ||
877 | } | ||
878 | else | ||
879 | { | 917 | { |
880 | return new OSDMap(); | 918 | if (webResponse != null) |
881 | } | 919 | { |
920 | using (Stream s = webResponse.GetResponseStream()) | ||
921 | using (StreamReader sr = new StreamReader(s)) | ||
922 | response_mapItems_reply = sr.ReadToEnd().Trim(); | ||
923 | } | ||
924 | else | ||
925 | { | ||
926 | return new OSDMap(); | ||
927 | } | ||
928 | } | ||
882 | } | 929 | } |
883 | catch (WebException) | 930 | catch (WebException) |
884 | { | 931 | { |
@@ -905,11 +952,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
905 | 952 | ||
906 | return responseMap; | 953 | return responseMap; |
907 | } | 954 | } |
908 | finally | ||
909 | { | ||
910 | if (sr != null) | ||
911 | sr.Close(); | ||
912 | } | ||
913 | 955 | ||
914 | OSD rezResponse = null; | 956 | OSD rezResponse = null; |
915 | try | 957 | try |
@@ -923,6 +965,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
923 | { | 965 | { |
924 | m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); | 966 | m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); |
925 | responseMap["connect"] = OSD.FromBoolean(false); | 967 | responseMap["connect"] = OSD.FromBoolean(false); |
968 | |||
926 | lock (m_blacklistedregions) | 969 | lock (m_blacklistedregions) |
927 | { | 970 | { |
928 | if (!m_blacklistedregions.ContainsKey(regionhandle)) | 971 | if (!m_blacklistedregions.ContainsKey(regionhandle)) |
@@ -955,7 +998,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
955 | /// <param name="maxY"></param> | 998 | /// <param name="maxY"></param> |
956 | public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) | 999 | public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) |
957 | { | 1000 | { |
958 | //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); | ||
959 | if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible | 1001 | if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible |
960 | { | 1002 | { |
961 | List<MapBlockData> response = new List<MapBlockData>(); | 1003 | List<MapBlockData> response = new List<MapBlockData>(); |
@@ -964,22 +1006,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
964 | // on an unloaded square. | 1006 | // on an unloaded square. |
965 | // But make sure: Look whether the one we requested is in there | 1007 | // But make sure: Look whether the one we requested is in there |
966 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, | 1008 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, |
967 | minX * (int)Constants.RegionSize, | 1009 | (int)Util.RegionToWorldLoc((uint)minX), (int)Util.RegionToWorldLoc((uint)maxX), |
968 | maxX * (int)Constants.RegionSize, | 1010 | (int)Util.RegionToWorldLoc((uint)minY), (int)Util.RegionToWorldLoc((uint)maxY) ); |
969 | minY * (int)Constants.RegionSize, | ||
970 | maxY * (int)Constants.RegionSize); | ||
971 | 1011 | ||
1012 | m_log.DebugFormat("[WORLD MAP MODULE] RequestMapBlocks min=<{0},{1}>, max=<{2},{3}>, flag={4}, cntFound={5}", | ||
1013 | minX, minY, maxX, maxY, flag.ToString("X"), regions.Count); | ||
972 | if (regions != null) | 1014 | if (regions != null) |
973 | { | 1015 | { |
974 | foreach (GridRegion r in regions) | 1016 | foreach (GridRegion r in regions) |
975 | { | 1017 | { |
976 | if ((r.RegionLocX == minX * (int)Constants.RegionSize) && | 1018 | if (r.RegionLocX == Util.RegionToWorldLoc((uint)minX) |
977 | (r.RegionLocY == minY * (int)Constants.RegionSize)) | 1019 | && r.RegionLocY == Util.RegionToWorldLoc((uint)minY) ) |
978 | { | 1020 | { |
979 | // found it => add it to response | 1021 | // found it => add it to response |
980 | MapBlockData block = new MapBlockData(); | 1022 | // Version 2 viewers can handle the larger regions |
981 | MapBlockFromGridRegion(block, r, flag); | 1023 | if ((flag & 2) == 2) |
982 | response.Add(block); | 1024 | response.AddRange(Map2BlockFromGridRegion(r, flag)); |
1025 | else | ||
1026 | response.Add(MapBlockFromGridRegion(r, flag)); | ||
983 | break; | 1027 | break; |
984 | } | 1028 | } |
985 | } | 1029 | } |
@@ -991,7 +1035,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
991 | MapBlockData block = new MapBlockData(); | 1035 | MapBlockData block = new MapBlockData(); |
992 | block.X = (ushort)minX; | 1036 | block.X = (ushort)minX; |
993 | block.Y = (ushort)minY; | 1037 | block.Y = (ushort)minY; |
994 | block.Access = 254; // means 'simulator is offline' | 1038 | block.Access = (byte)SimAccess.Down; // means 'simulator is offline' |
1039 | // block.Access = (byte)SimAccess.NonExistent; | ||
995 | response.Add(block); | 1040 | response.Add(block); |
996 | } | 1041 | } |
997 | // The lower 16 bits are an unsigned int16 | 1042 | // The lower 16 bits are an unsigned int16 |
@@ -1008,39 +1053,94 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1008 | { | 1053 | { |
1009 | List<MapBlockData> mapBlocks = new List<MapBlockData>(); | 1054 | List<MapBlockData> mapBlocks = new List<MapBlockData>(); |
1010 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, | 1055 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, |
1011 | (minX - 4) * (int)Constants.RegionSize, | 1056 | (int)Util.RegionToWorldLoc((uint)(minX - 4)), (int)Util.RegionToWorldLoc((uint)(maxX + 4)), |
1012 | (maxX + 4) * (int)Constants.RegionSize, | 1057 | (int)Util.RegionToWorldLoc((uint)(minY - 4)), (int)Util.RegionToWorldLoc((uint)(maxY + 4)) ); |
1013 | (minY - 4) * (int)Constants.RegionSize, | 1058 | //m_log.DebugFormat("{0} GetAndSendBlocks. min=<{1},{2}>, max=<{3},{4}>, cntFound={5}", |
1014 | (maxY + 4) * (int)Constants.RegionSize); | 1059 | // LogHeader, minX, minY, maxX, maxY, regions.Count); |
1015 | foreach (GridRegion r in regions) | 1060 | foreach (GridRegion r in regions) |
1016 | { | 1061 | { |
1017 | MapBlockData block = new MapBlockData(); | 1062 | // Version 2 viewers can handle the larger regions |
1018 | MapBlockFromGridRegion(block, r, flag); | 1063 | if ((flag & 2) == 2) |
1019 | mapBlocks.Add(block); | 1064 | mapBlocks.AddRange(Map2BlockFromGridRegion(r, flag)); |
1065 | else | ||
1066 | mapBlocks.Add(MapBlockFromGridRegion(r, flag)); | ||
1020 | } | 1067 | } |
1021 | remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); | 1068 | remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); |
1022 | 1069 | ||
1023 | return mapBlocks; | 1070 | return mapBlocks; |
1024 | } | 1071 | } |
1025 | 1072 | ||
1026 | protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) | 1073 | // Fill a passed MapBlockData from a GridRegion |
1074 | public MapBlockData MapBlockFromGridRegion(GridRegion r, uint flag) | ||
1027 | { | 1075 | { |
1076 | MapBlockData block = new MapBlockData(); | ||
1077 | |||
1028 | block.Access = r.Access; | 1078 | block.Access = r.Access; |
1029 | switch (flag & 0xffff) | 1079 | switch (flag & 0xffff) |
1030 | { | 1080 | { |
1031 | case 0: | 1081 | case 0: |
1032 | block.MapImageId = r.TerrainImage; | 1082 | block.MapImageId = r.TerrainImage; |
1033 | break; | 1083 | break; |
1034 | case 2: | 1084 | case 2: |
1035 | block.MapImageId = r.ParcelImage; | 1085 | block.MapImageId = r.ParcelImage; |
1036 | break; | 1086 | break; |
1037 | default: | 1087 | default: |
1038 | block.MapImageId = UUID.Zero; | 1088 | block.MapImageId = UUID.Zero; |
1039 | break; | 1089 | break; |
1040 | } | 1090 | } |
1041 | block.Name = r.RegionName; | 1091 | block.Name = r.RegionName; |
1042 | block.X = (ushort)(r.RegionLocX / Constants.RegionSize); | 1092 | block.X = (ushort)Util.WorldToRegionLoc((uint)r.RegionLocX); |
1043 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); | 1093 | block.Y = (ushort)Util.WorldToRegionLoc((uint)r.RegionLocY); |
1094 | block.SizeX = (ushort) r.RegionSizeX; | ||
1095 | block.SizeY = (ushort) r.RegionSizeY; | ||
1096 | |||
1097 | return block; | ||
1098 | } | ||
1099 | |||
1100 | public List<MapBlockData> Map2BlockFromGridRegion(GridRegion r, uint flag) | ||
1101 | { | ||
1102 | List<MapBlockData> blocks = new List<MapBlockData>(); | ||
1103 | MapBlockData block = new MapBlockData(); | ||
1104 | if (r == null) | ||
1105 | { | ||
1106 | block.Access = (byte)SimAccess.Down; | ||
1107 | block.MapImageId = UUID.Zero; | ||
1108 | blocks.Add(block); | ||
1109 | } | ||
1110 | else | ||
1111 | { | ||
1112 | block.Access = r.Access; | ||
1113 | switch (flag & 0xffff) | ||
1114 | { | ||
1115 | case 0: | ||
1116 | block.MapImageId = r.TerrainImage; | ||
1117 | break; | ||
1118 | case 2: | ||
1119 | block.MapImageId = r.ParcelImage; | ||
1120 | break; | ||
1121 | default: | ||
1122 | block.MapImageId = UUID.Zero; | ||
1123 | break; | ||
1124 | } | ||
1125 | block.Name = r.RegionName; | ||
1126 | block.X = (ushort)(r.RegionLocX / Constants.RegionSize); | ||
1127 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); | ||
1128 | block.SizeX = (ushort)r.RegionSizeX; | ||
1129 | block.SizeY = (ushort)r.RegionSizeY; | ||
1130 | blocks.Add(block); | ||
1131 | } | ||
1132 | return blocks; | ||
1133 | } | ||
1134 | |||
1135 | |||
1136 | public Hashtable OnHTTPThrottled(Hashtable keysvals) | ||
1137 | { | ||
1138 | Hashtable reply = new Hashtable(); | ||
1139 | int statuscode = 500; | ||
1140 | reply["str_response_string"] = ""; | ||
1141 | reply["int_response_code"] = statuscode; | ||
1142 | reply["content_type"] = "text/plain"; | ||
1143 | return reply; | ||
1044 | } | 1144 | } |
1045 | 1145 | ||
1046 | public Hashtable OnHTTPGetMapImage(Hashtable keysvals) | 1146 | public Hashtable OnHTTPGetMapImage(Hashtable keysvals) |
@@ -1052,7 +1152,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1052 | 1152 | ||
1053 | if (myMapImageJPEG.Length == 0) | 1153 | if (myMapImageJPEG.Length == 0) |
1054 | { | 1154 | { |
1055 | MemoryStream imgstream = new MemoryStream(); | 1155 | MemoryStream imgstream = null; |
1056 | Bitmap mapTexture = new Bitmap(1,1); | 1156 | Bitmap mapTexture = new Bitmap(1,1); |
1057 | ManagedImage managedImage; | 1157 | ManagedImage managedImage; |
1058 | Image image = (Image)mapTexture; | 1158 | Image image = (Image)mapTexture; |
@@ -1099,10 +1199,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1099 | image.Dispose(); | 1199 | image.Dispose(); |
1100 | 1200 | ||
1101 | if (imgstream != null) | 1201 | if (imgstream != null) |
1102 | { | ||
1103 | imgstream.Close(); | ||
1104 | imgstream.Dispose(); | 1202 | imgstream.Dispose(); |
1105 | } | ||
1106 | } | 1203 | } |
1107 | } | 1204 | } |
1108 | else | 1205 | else |
@@ -1161,17 +1258,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1161 | 1258 | ||
1162 | List<MapBlockData> mapBlocks = new List<MapBlockData>(); | 1259 | List<MapBlockData> mapBlocks = new List<MapBlockData>(); |
1163 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, | 1260 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, |
1164 | (int)(m_scene.RegionInfo.RegionLocX - 9) * (int)Constants.RegionSize, | 1261 | (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocX - 9), |
1165 | (int)(m_scene.RegionInfo.RegionLocX + 9) * (int)Constants.RegionSize, | 1262 | (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocX + 9), |
1166 | (int)(m_scene.RegionInfo.RegionLocY - 9) * (int)Constants.RegionSize, | 1263 | (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocY - 9), |
1167 | (int)(m_scene.RegionInfo.RegionLocY + 9) * (int)Constants.RegionSize); | 1264 | (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocY + 9)); |
1168 | List<AssetBase> textures = new List<AssetBase>(); | 1265 | List<AssetBase> textures = new List<AssetBase>(); |
1169 | List<Image> bitImages = new List<Image>(); | 1266 | List<Image> bitImages = new List<Image>(); |
1170 | 1267 | ||
1171 | foreach (GridRegion r in regions) | 1268 | foreach (GridRegion r in regions) |
1172 | { | 1269 | { |
1173 | MapBlockData mapBlock = new MapBlockData(); | 1270 | MapBlockData mapBlock = MapBlockFromGridRegion(r, 0); |
1174 | MapBlockFromGridRegion(mapBlock, r, 0); | ||
1175 | AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); | 1271 | AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); |
1176 | 1272 | ||
1177 | if (texAsset != null) | 1273 | if (texAsset != null) |
@@ -1217,12 +1313,34 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1217 | m_scene.RegionInfo.RegionName, exportPath); | 1313 | m_scene.RegionInfo.RegionName, exportPath); |
1218 | } | 1314 | } |
1219 | 1315 | ||
1316 | public void HandleGenerateMapConsoleCommand(string module, string[] cmdparams) | ||
1317 | { | ||
1318 | Scene consoleScene = m_scene.ConsoleScene(); | ||
1319 | |||
1320 | if (consoleScene != null && consoleScene != m_scene) | ||
1321 | return; | ||
1322 | |||
1323 | if (m_mapImageGenerator == null) | ||
1324 | { | ||
1325 | Console.WriteLine("No map image generator available for {0}", m_scene.Name); | ||
1326 | return; | ||
1327 | } | ||
1328 | |||
1329 | using (Bitmap mapbmp = m_mapImageGenerator.CreateMapTile()) | ||
1330 | { | ||
1331 | GenerateMaptile(mapbmp); | ||
1332 | m_mapImageServiceModule.UploadMapTile(m_scene, mapbmp); | ||
1333 | } | ||
1334 | } | ||
1335 | |||
1220 | public OSD HandleRemoteMapItemRequest(string path, OSD request, string endpoint) | 1336 | public OSD HandleRemoteMapItemRequest(string path, OSD request, string endpoint) |
1221 | { | 1337 | { |
1222 | uint xstart = 0; | 1338 | uint xstart = 0; |
1223 | uint ystart = 0; | 1339 | uint ystart = 0; |
1224 | 1340 | ||
1225 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); | 1341 | Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); |
1342 | // m_log.DebugFormat("{0} HandleRemoteMapItemRequest. loc=<{1},{2}>", | ||
1343 | // LogHeader, Util.WorldToRegionLoc(xstart), Util.WorldToRegionLoc(ystart)); | ||
1226 | 1344 | ||
1227 | // Service 6 (MAP_ITEM_AGENTS_LOCATION; green dots) | 1345 | // Service 6 (MAP_ITEM_AGENTS_LOCATION; green dots) |
1228 | 1346 | ||
@@ -1337,20 +1455,35 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1337 | 1455 | ||
1338 | public void GenerateMaptile() | 1456 | public void GenerateMaptile() |
1339 | { | 1457 | { |
1340 | // Cannot create a map for a nonexistant heightmap | 1458 | // Cannot create a map for a nonexistent heightmap |
1341 | if (m_scene.Heightmap == null) | 1459 | if (m_scene.Heightmap == null) |
1342 | return; | 1460 | return; |
1343 | 1461 | ||
1344 | //create a texture asset of the terrain | 1462 | m_log.DebugFormat("[WORLD MAP]: Generating map image for {0}", m_scene.Name); |
1345 | IMapImageGenerator terrain = m_scene.RequestModuleInterface<IMapImageGenerator>(); | 1463 | |
1346 | if (terrain == null) | 1464 | using (Bitmap mapbmp = m_mapImageGenerator.CreateMapTile()) |
1347 | return; | 1465 | { |
1466 | // V1 (This Module) | ||
1467 | GenerateMaptile(mapbmp); | ||
1468 | |||
1469 | // v2/3 (MapImageServiceModule) | ||
1470 | m_mapImageServiceModule.UploadMapTile(m_scene, mapbmp); | ||
1471 | } | ||
1472 | } | ||
1348 | 1473 | ||
1349 | m_log.DebugFormat("[WORLD MAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName); | 1474 | private void GenerateMaptile(Bitmap mapbmp) |
1475 | { | ||
1476 | byte[] data; | ||
1350 | 1477 | ||
1351 | byte[] data = terrain.WriteJpeg2000Image(); | 1478 | try |
1352 | if (data == null) | 1479 | { |
1480 | data = OpenJPEG.EncodeFromImage(mapbmp, true); | ||
1481 | } | ||
1482 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke | ||
1483 | { | ||
1484 | m_log.Error("[WORLD MAP]: Failed generating terrain map: " + e); | ||
1353 | return; | 1485 | return; |
1486 | } | ||
1354 | 1487 | ||
1355 | byte[] overlay = GenerateOverlay(); | 1488 | byte[] overlay = GenerateOverlay(); |
1356 | 1489 | ||
@@ -1448,62 +1581,80 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1448 | 1581 | ||
1449 | private Byte[] GenerateOverlay() | 1582 | private Byte[] GenerateOverlay() |
1450 | { | 1583 | { |
1451 | Bitmap overlay = new Bitmap(256, 256); | 1584 | // These need to be ints for bitmap generation |
1585 | int regionSizeX = (int)m_scene.RegionInfo.RegionSizeX; | ||
1586 | int regionSizeY = (int)m_scene.RegionInfo.RegionSizeY; | ||
1452 | 1587 | ||
1453 | bool[,] saleBitmap = new bool[64, 64]; | 1588 | int landTileSize = LandManagementModule.LandUnit; |
1454 | for (int x = 0 ; x < 64 ; x++) | 1589 | int regionLandTilesX = regionSizeX / landTileSize; |
1455 | { | 1590 | int regionLandTilesY = regionSizeY / landTileSize; |
1456 | for (int y = 0 ; y < 64 ; y++) | ||
1457 | saleBitmap[x, y] = false; | ||
1458 | } | ||
1459 | 1591 | ||
1460 | bool landForSale = false; | 1592 | using (Bitmap overlay = new Bitmap(regionSizeX, regionSizeY)) |
1593 | { | ||
1594 | bool[,] saleBitmap = new bool[regionLandTilesX, regionLandTilesY]; | ||
1595 | for (int x = 0; x < regionLandTilesX; x++) | ||
1596 | { | ||
1597 | for (int y = 0; y < regionLandTilesY; y++) | ||
1598 | saleBitmap[x, y] = false; | ||
1599 | } | ||
1461 | 1600 | ||
1462 | List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); | 1601 | bool landForSale = false; |
1463 | 1602 | ||
1464 | Color background = Color.FromArgb(0, 0, 0, 0); | 1603 | List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); |
1465 | SolidBrush transparent = new SolidBrush(background); | ||
1466 | Graphics g = Graphics.FromImage(overlay); | ||
1467 | g.FillRectangle(transparent, 0, 0, 256, 256); | ||
1468 | 1604 | ||
1469 | SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); | 1605 | Color background = Color.FromArgb(0, 0, 0, 0); |
1470 | 1606 | ||
1471 | foreach (ILandObject land in parcels) | 1607 | using (Graphics g = Graphics.FromImage(overlay)) |
1472 | { | ||
1473 | // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); | ||
1474 | if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) | ||
1475 | { | 1608 | { |
1476 | landForSale = true; | 1609 | using (SolidBrush transparent = new SolidBrush(background)) |
1610 | g.FillRectangle(transparent, 0, 0, regionSizeX, regionSizeY); | ||
1477 | 1611 | ||
1478 | saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); | 1612 | foreach (ILandObject land in parcels) |
1479 | } | 1613 | { |
1480 | } | 1614 | // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); |
1615 | if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) | ||
1616 | { | ||
1617 | landForSale = true; | ||
1481 | 1618 | ||
1482 | if (!landForSale) | 1619 | saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); |
1483 | { | 1620 | } |
1484 | m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not generating overlay", m_scene.RegionInfo.RegionName); | 1621 | } |
1485 | return null; | 1622 | |
1486 | } | 1623 | if (!landForSale) |
1624 | { | ||
1625 | m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not generating overlay", m_scene.RegionInfo.RegionName); | ||
1626 | return null; | ||
1627 | } | ||
1487 | 1628 | ||
1488 | m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); | 1629 | m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); |
1489 | 1630 | ||
1490 | for (int x = 0 ; x < 64 ; x++) | 1631 | using (SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9))) |
1491 | { | 1632 | { |
1492 | for (int y = 0 ; y < 64 ; y++) | 1633 | for (int x = 0 ; x < regionLandTilesX ; x++) |
1634 | { | ||
1635 | for (int y = 0 ; y < regionLandTilesY ; y++) | ||
1636 | { | ||
1637 | if (saleBitmap[x, y]) | ||
1638 | g.FillRectangle( | ||
1639 | yellow, x * landTileSize, | ||
1640 | regionSizeX - landTileSize - (y * landTileSize), | ||
1641 | landTileSize, | ||
1642 | landTileSize); | ||
1643 | } | ||
1644 | } | ||
1645 | } | ||
1646 | } | ||
1647 | |||
1648 | try | ||
1493 | { | 1649 | { |
1494 | if (saleBitmap[x, y]) | 1650 | return OpenJPEG.EncodeFromImage(overlay, true); |
1495 | g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); | 1651 | } |
1652 | catch (Exception e) | ||
1653 | { | ||
1654 | m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); | ||
1496 | } | 1655 | } |
1497 | } | 1656 | } |
1498 | 1657 | ||
1499 | try | ||
1500 | { | ||
1501 | return OpenJPEG.EncodeFromImage(overlay, true); | ||
1502 | } | ||
1503 | catch (Exception e) | ||
1504 | { | ||
1505 | m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); | ||
1506 | } | ||
1507 | return null; | 1658 | return null; |
1508 | } | 1659 | } |
1509 | } | 1660 | } |