aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/WorldMap
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World/WorldMap')
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs94
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs517
2 files changed, 388 insertions, 223 deletions
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 708a9a2..d862f18 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -49,6 +49,18 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
49 List<Scene> m_scenes = new List<Scene>(); 49 List<Scene> m_scenes = new List<Scene>();
50 List<UUID> m_Clients; 50 List<UUID> m_Clients;
51 51
52 IWorldMapModule m_WorldMap;
53 IWorldMapModule WorldMap
54 {
55 get
56 {
57 if (m_WorldMap == null)
58 m_WorldMap = m_scene.RequestModuleInterface<IWorldMapModule>();
59 return m_WorldMap;
60 }
61
62 }
63
52 #region ISharedRegionModule Members 64 #region ISharedRegionModule Members
53 public void Initialise(IConfigSource source) 65 public void Initialise(IConfigSource source)
54 { 66 {
@@ -64,6 +76,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
64 m_scenes.Add(scene); 76 m_scenes.Add(scene);
65 scene.EventManager.OnNewClient += OnNewClient; 77 scene.EventManager.OnNewClient += OnNewClient;
66 m_Clients = new List<UUID>(); 78 m_Clients = new List<UUID>();
79
67 } 80 }
68 81
69 public void RemoveRegion(Scene scene) 82 public void RemoveRegion(Scene scene)
@@ -129,7 +142,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
129 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) 142 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
130 { 143 {
131 List<MapBlockData> blocks = new List<MapBlockData>(); 144 List<MapBlockData> blocks = new List<MapBlockData>();
132 MapBlockData data;
133 if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) 145 if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4))
134 { 146 {
135 // final block, closing the search result 147 // final block, closing the search result
@@ -143,50 +155,51 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
143 } 155 }
144 156
145 157
146 //m_log.DebugFormat("MAP NAME=({0})", mapName); 158 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
147 159
148 // Hack to get around the fact that ll V3 now drops the port from the
149 // map name. See https://jira.secondlife.com/browse/VWR-28570
150 //
151 // Caller, use this magic form instead:
152 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128
153 // or url encode if possible.
154 // the hacks we do with this viewer...
155 //
156 string mapNameOrig = mapName; 160 string mapNameOrig = mapName;
157 if (mapName.Contains("|")) 161 if (regionInfos.Count == 0)
158 mapName = mapName.Replace('|', ':'); 162 {
159 if (mapName.Contains("+")) 163 // Hack to get around the fact that ll V3 now drops the port from the
160 mapName = mapName.Replace('+', ' '); 164 // map name. See https://jira.secondlife.com/browse/VWR-28570
161 if (mapName.Contains("!")) 165 //
162 mapName = mapName.Replace('!', '/'); 166 // Caller, use this magic form instead:
167 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128
168 // or url encode if possible.
169 // the hacks we do with this viewer...
170 //
171 if (mapName.Contains("|"))
172 mapName = mapName.Replace('|', ':');
173 if (mapName.Contains("+"))
174 mapName = mapName.Replace('+', ' ');
175 if (mapName.Contains("!"))
176 mapName = mapName.Replace('!', '/');
177
178 if (mapName != mapNameOrig)
179 regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
180 }
163 181
164 // try to fetch from GridServer
165 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
166
167 m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); 182 m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags);
183
168 if (regionInfos.Count > 0) 184 if (regionInfos.Count > 0)
169 { 185 {
170 foreach (GridRegion info in regionInfos) 186 foreach (GridRegion info in regionInfos)
171 { 187 {
172 data = new MapBlockData(); 188 if ((flags & 2) == 2) // V2 sends this
173 data.Agents = 0; 189 {
174 data.Access = info.Access; 190 List<MapBlockData> datas = WorldMap.Map2BlockFromGridRegion(info, flags);
175 if (flags == 2) // V2 sends this 191 // ugh! V2-3 is very sensitive about the result being
176 data.MapImageId = UUID.Zero; 192 // exactly the same as the requested name
177 else 193 if (regionInfos.Count == 1 && (mapName != mapNameOrig))
178 data.MapImageId = info.TerrainImage; 194 datas.ForEach(d => d.Name = mapNameOrig);
179 // ugh! V2-3 is very sensitive about the result being 195
180 // exactly the same as the requested name 196 blocks.AddRange(datas);
181 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+")) 197 }
182 data.Name = mapNameOrig;
183 else 198 else
184 data.Name = info.RegionName; 199 {
185 data.RegionFlags = 0; // TODO not used? 200 MapBlockData data = WorldMap.MapBlockFromGridRegion(info, flags);
186 data.WaterHeight = 0; // not used 201 blocks.Add(data);
187 data.X = (ushort)(info.RegionLocX / Constants.RegionSize); 202 }
188 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize);
189 blocks.Add(data);
190 } 203 }
191 } 204 }
192 205
@@ -204,8 +217,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
204 { 217 {
205 if (regionInfos.Count == 0) 218 if (regionInfos.Count == 0)
206 remoteClient.SendAlertMessage("No regions found with that name."); 219 remoteClient.SendAlertMessage("No regions found with that name.");
207 else if (regionInfos.Count == 1) 220 // this seems unnecessary because found regions will show up in the search results
208 remoteClient.SendAlertMessage("Region found!"); 221 //else if (regionInfos.Count == 1)
222 // remoteClient.SendAlertMessage("Region found!");
209 } 223 }
210 } 224 }
211 225
@@ -214,7 +228,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
214 // final block, closing the search result 228 // final block, closing the search result
215 MapBlockData data = new MapBlockData(); 229 MapBlockData data = new MapBlockData();
216 data.Agents = 0; 230 data.Agents = 0;
217 data.Access = 255; 231 data.Access = (byte)SimAccess.NonExistent;
218 data.MapImageId = UUID.Zero; 232 data.MapImageId = UUID.Zero;
219 data.Name = ""; 233 data.Name = "";
220 data.RegionFlags = 0; 234 data.RegionFlags = 0;
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 }