aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs161
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs497
3 files changed, 383 insertions, 279 deletions
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index 0c60391..4f18b53 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -90,9 +90,9 @@ namespace OpenSim.Region.CoreModules.Hypergrid
90 } 90 }
91 } 91 }
92 92
93 protected override List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 93 protected override List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
94 { 94 {
95 List<MapBlockData> mapBlocks = base.GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); 95 List<MapBlockData> mapBlocks = base.GetAndSendBlocksInternal(remoteClient, minX, minY, maxX, maxY, flag);
96 lock (m_SeenMapBlocks) 96 lock (m_SeenMapBlocks)
97 { 97 {
98 if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId)) 98 if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId))
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 4e6bfb8..2417b1a 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -86,90 +86,93 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
86 86
87 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) 87 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
88 { 88 {
89 if (mapName.Length < 2) 89 Util.FireAndForget(x =>
90 { 90 {
91 remoteClient.SendAlertMessage("Use a search string with at least 2 characters"); 91 if (mapName.Length < 2)
92 return; 92 {
93 } 93 remoteClient.SendAlertMessage("Use a search string with at least 2 characters");
94 return;
95 }
94 96
95 //m_log.DebugFormat("MAP NAME=({0})", mapName); 97 //m_log.DebugFormat("MAP NAME=({0})", mapName);
96 98
97 // Hack to get around the fact that ll V3 now drops the port from the 99 // Hack to get around the fact that ll V3 now drops the port from the
98 // map name. See https://jira.secondlife.com/browse/VWR-28570 100 // map name. See https://jira.secondlife.com/browse/VWR-28570
99 // 101 //
100 // Caller, use this magic form instead: 102 // Caller, use this magic form instead:
101 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 103 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128
102 // or url encode if possible. 104 // or url encode if possible.
103 // the hacks we do with this viewer... 105 // the hacks we do with this viewer...
104 // 106 //
105 string mapNameOrig = mapName; 107 string mapNameOrig = mapName;
106 if (mapName.Contains("|")) 108 if (mapName.Contains("|"))
107 mapName = mapName.Replace('|', ':'); 109 mapName = mapName.Replace('|', ':');
108 if (mapName.Contains("+")) 110 if (mapName.Contains("+"))
109 mapName = mapName.Replace('+', ' '); 111 mapName = mapName.Replace('+', ' ');
110 if (mapName.Contains("!")) 112 if (mapName.Contains("!"))
111 mapName = mapName.Replace('!', '/'); 113 mapName = mapName.Replace('!', '/');
112 114
113 // try to fetch from GridServer 115 // try to fetch from GridServer
114 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); 116 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
115// if (regionInfos.Count == 0) 117 // if (regionInfos.Count == 0)
116// remoteClient.SendAlertMessage("Hyperlink could not be established."); 118 // remoteClient.SendAlertMessage("Hyperlink could not be established.");
117 119
118 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); 120 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
119 List<MapBlockData> blocks = new List<MapBlockData>(); 121 List<MapBlockData> blocks = new List<MapBlockData>();
120 122
121 MapBlockData data; 123 MapBlockData data;
122 if (regionInfos.Count > 0) 124 if (regionInfos.Count > 0)
123 {
124 foreach (GridRegion info in regionInfos)
125 { 125 {
126 data = new MapBlockData(); 126 foreach (GridRegion info in regionInfos)
127 data.Agents = 0; 127 {
128 data.Access = info.Access; 128 data = new MapBlockData();
129 if (flags == 2) // V2 sends this 129 data.Agents = 0;
130 data.MapImageId = UUID.Zero; 130 data.Access = info.Access;
131 else 131 if (flags == 2) // V2 sends this
132 data.MapImageId = info.TerrainImage; 132 data.MapImageId = UUID.Zero;
133 // ugh! V2-3 is very sensitive about the result being 133 else
134 // exactly the same as the requested name 134 data.MapImageId = info.TerrainImage;
135 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+")) 135 // ugh! V2-3 is very sensitive about the result being
136 data.Name = mapNameOrig; 136 // exactly the same as the requested name
137 else 137 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
138 data.Name = info.RegionName; 138 data.Name = mapNameOrig;
139 data.RegionFlags = 0; // TODO not used? 139 else
140 data.WaterHeight = 0; // not used 140 data.Name = info.RegionName;
141 data.X = (ushort)(info.RegionLocX / Constants.RegionSize); 141 data.RegionFlags = 0; // TODO not used?
142 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize); 142 data.WaterHeight = 0; // not used
143 blocks.Add(data); 143 data.X = (ushort)(info.RegionLocX / Constants.RegionSize);
144 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize);
145 blocks.Add(data);
146 }
144 } 147 }
145 }
146 148
147 // final block, closing the search result 149 // final block, closing the search result
148 data = new MapBlockData(); 150 data = new MapBlockData();
149 data.Agents = 0; 151 data.Agents = 0;
150 data.Access = 255; 152 data.Access = 255;
151 data.MapImageId = UUID.Zero; 153 data.MapImageId = UUID.Zero;
152 data.Name = mapName; 154 data.Name = mapName;
153 data.RegionFlags = 0; 155 data.RegionFlags = 0;
154 data.WaterHeight = 0; // not used 156 data.WaterHeight = 0; // not used
155 data.X = 0; 157 data.X = 0;
156 data.Y = 0; 158 data.Y = 0;
157 blocks.Add(data); 159 blocks.Add(data);
158 160
159 // flags are agent flags sent from the viewer. 161 // flags are agent flags sent from the viewer.
160 // they have different values depending on different viewers, apparently 162 // they have different values depending on different viewers, apparently
161 remoteClient.SendMapBlock(blocks, flags); 163 remoteClient.SendMapBlock(blocks, flags);
162 164
163 // send extra user messages for V3 165 // send extra user messages for V3
164 // because the UI is very confusing 166 // because the UI is very confusing
165 // while we don't fix the hard-coded urls 167 // while we don't fix the hard-coded urls
166 if (flags == 2) 168 if (flags == 2)
167 { 169 {
168 if (regionInfos.Count == 0) 170 if (regionInfos.Count == 0)
169 remoteClient.SendAgentAlertMessage("No regions found with that name.", true); 171 remoteClient.SendAgentAlertMessage("No regions found with that name.", true);
170 else if (regionInfos.Count == 1) 172 else if (regionInfos.Count == 1)
171 remoteClient.SendAgentAlertMessage("Region found!", false); 173 remoteClient.SendAgentAlertMessage("Region found!", false);
172 } 174 }
175 });
173 } 176 }
174 177
175// private Scene GetClientScene(IClientAPI client) 178// private Scene GetClientScene(IClientAPI client)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 00be5df..309856f 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -63,7 +63,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
63 private static readonly UUID STOP_UUID = UUID.Random(); 63 private static readonly UUID STOP_UUID = UUID.Random();
64 private static readonly string m_mapLayerPath = "0001/"; 64 private static readonly string m_mapLayerPath = "0001/";
65 65
66 private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>(); 66 private ManualResetEvent queueEvent = new ManualResetEvent(false);
67 private Queue<MapRequestState> requests = new Queue<MapRequestState>();
68
69 private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false);
70 private Dictionary<UUID, Queue<MapBlockRequestData>> m_mapBlockRequests = new Dictionary<UUID, Queue<MapBlockRequestData>>();
67 71
68 protected Scene m_scene; 72 protected Scene m_scene;
69 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 73 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
@@ -71,7 +75,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
71 private int blacklistTimeout = 10*60*1000; // 10 minutes 75 private int blacklistTimeout = 10*60*1000; // 10 minutes
72 private byte[] myMapImageJPEG; 76 private byte[] myMapImageJPEG;
73 protected volatile bool m_Enabled = false; 77 protected volatile bool m_Enabled = false;
74 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>();
75 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>(); 78 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>();
76 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>(); 79 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>();
77 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>(); 80 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>();
@@ -228,54 +231,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
228 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is 231 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
229 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. 232 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
230 233
231 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 234 //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
232 { 235 //{
233 ScenePresence avatarPresence = null; 236 // ScenePresence avatarPresence = null;
234 237
235 m_scene.TryGetScenePresence(agentID, out avatarPresence); 238 // m_scene.TryGetScenePresence(agentID, out avatarPresence);
236 239
237 if (avatarPresence != null) 240 // if (avatarPresence != null)
238 { 241 // {
239 bool lookup = false; 242 // bool lookup = false;
240 243
241 lock (cachedMapBlocks) 244 // lock (cachedMapBlocks)
242 { 245 // {
243 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) 246 // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
244 { 247 // {
245 List<MapBlockData> mapBlocks; 248 // List<MapBlockData> mapBlocks;
246 249
247 mapBlocks = cachedMapBlocks; 250 // mapBlocks = cachedMapBlocks;
248 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 251 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
249 } 252 // }
250 else 253 // else
251 { 254 // {
252 lookup = true; 255 // lookup = true;
253 } 256 // }
254 } 257 // }
255 if (lookup) 258 // if (lookup)
256 { 259 // {
257 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 260 // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
258 261
259 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 262 // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
260 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, 263 // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
261 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, 264 // (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
262 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, 265 // (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
263 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); 266 // (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
264 foreach (GridRegion r in regions) 267 // foreach (GridRegion r in regions)
265 { 268 // {
266 MapBlockData block = new MapBlockData(); 269 // MapBlockData block = new MapBlockData();
267 MapBlockFromGridRegion(block, r, 0); 270 // MapBlockFromGridRegion(block, r, 0);
268 mapBlocks.Add(block); 271 // mapBlocks.Add(block);
269 } 272 // }
270 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 273 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
271 274
272 lock (cachedMapBlocks) 275 // lock (cachedMapBlocks)
273 cachedMapBlocks = mapBlocks; 276 // cachedMapBlocks = mapBlocks;
274 277
275 cachedTime = Util.UnixTimeSinceEpoch(); 278 // cachedTime = Util.UnixTimeSinceEpoch();
276 } 279 // }
277 } 280 // }
278 } 281 //}
279 282
280 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 283 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
281 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 284 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
@@ -302,8 +305,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
302 protected static OSDMapLayer GetOSDMapLayerResponse() 305 protected static OSDMapLayer GetOSDMapLayerResponse()
303 { 306 {
304 OSDMapLayer mapLayer = new OSDMapLayer(); 307 OSDMapLayer mapLayer = new OSDMapLayer();
305 mapLayer.Right = 5000; 308 mapLayer.Right = 2048;
306 mapLayer.Top = 5000; 309 mapLayer.Top = 2048;
307 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); 310 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
308 311
309 return mapLayer; 312 return mapLayer;
@@ -332,6 +335,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
332 { 335 {
333 m_rootAgents.Remove(AgentId); 336 m_rootAgents.Remove(AgentId);
334 } 337 }
338 lock (m_mapBlockRequestEvent)
339 {
340 if (m_mapBlockRequests.ContainsKey(AgentId))
341 m_mapBlockRequests.Remove(AgentId);
342 }
335 } 343 }
336 #endregion 344 #endregion
337 345
@@ -354,6 +362,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
354 ThreadPriority.BelowNormal, 362 ThreadPriority.BelowNormal,
355 true, 363 true,
356 true); 364 true);
365 Watchdog.StartThread(
366 MapBlockSendThread,
367 string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
368 ThreadPriority.BelowNormal,
369 true,
370 true);
357 } 371 }
358 372
359 /// <summary> 373 /// <summary>
@@ -369,7 +383,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
369 st.itemtype=0; 383 st.itemtype=0;
370 st.regionhandle=0; 384 st.regionhandle=0;
371 385
372 requests.Enqueue(st); 386 lock (requests)
387 {
388 queueEvent.Set();
389 requests.Enqueue(st);
390 }
391
392 MapBlockRequestData req = new MapBlockRequestData();
393
394 req.client = null;
395 req.minX = 0;
396 req.maxX = 0;
397 req.minY = 0;
398 req.maxY = 0;
399 req.flags = 0;
400
401 lock (m_mapBlockRequestEvent)
402 {
403 m_mapBlockRequests[UUID.Zero] = new Queue<MapBlockRequestData>();
404 m_mapBlockRequests[UUID.Zero].Enqueue(req);
405 m_mapBlockRequestEvent.Set();
406 }
373 } 407 }
374 408
375 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 409 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
@@ -525,7 +559,21 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
525 { 559 {
526 while (true) 560 while (true)
527 { 561 {
528 MapRequestState st = requests.Dequeue(1000); 562 MapRequestState st = new MapRequestState();
563 bool valid = false;
564 queueEvent.WaitOne();
565 lock (requests)
566 {
567 if (requests.Count > 0)
568 {
569 st = requests.Dequeue();
570 valid = true;
571 }
572 if (requests.Count == 0)
573 queueEvent.Reset();
574 }
575 if (!valid)
576 continue;
529 577
530 // end gracefully 578 // end gracefully
531 if (st.agentID == STOP_UUID) 579 if (st.agentID == STOP_UUID)
@@ -543,13 +591,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
543 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) 591 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
544 { 592 {
545 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break 593 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
546 Thread.Sleep(80); 594 Thread.Sleep(100);
547 595
548 RequestMapItemsDelegate d = RequestMapItemsAsync;
549 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
550 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
551 //RequestMapItemsCompleted(response);
552 Interlocked.Increment(ref nAsyncRequests); 596 Interlocked.Increment(ref nAsyncRequests);
597 Util.FireAndForget(x =>
598 {
599 RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
600 });
553 } 601 }
554 } 602 }
555 603
@@ -571,110 +619,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
571 /// <param name="state"></param> 619 /// <param name="state"></param>
572 public void EnqueueMapItemRequest(MapRequestState state) 620 public void EnqueueMapItemRequest(MapRequestState state)
573 { 621 {
574 requests.Enqueue(state); 622 lock (requests)
575 }
576
577 /// <summary>
578 /// Sends the mapitem response to the IClientAPI
579 /// </summary>
580 /// <param name="response">The OSDMap Response for the mapitem</param>
581 private void RequestMapItemsCompleted(IAsyncResult iar)
582 {
583 AsyncResult result = (AsyncResult)iar;
584 RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
585
586 OSDMap response = (OSDMap)icon.EndInvoke(iar);
587
588 Interlocked.Decrement(ref nAsyncRequests);
589
590 if (!response.ContainsKey("requestID"))
591 return;
592
593 UUID requestID = response["requestID"].AsUUID();
594
595 if (requestID != UUID.Zero)
596 { 623 {
597 MapRequestState mrs = new MapRequestState(); 624 queueEvent.Set();
598 mrs.agentID = UUID.Zero; 625 requests.Enqueue(state);
599 lock (m_openRequests)
600 {
601 if (m_openRequests.ContainsKey(requestID))
602 {
603 mrs = m_openRequests[requestID];
604 m_openRequests.Remove(requestID);
605 }
606 }
607
608 if (mrs.agentID != UUID.Zero)
609 {
610 ScenePresence av = null;
611 m_scene.TryGetScenePresence(mrs.agentID, out av);
612 if (av != null)
613 {
614 if (response.ContainsKey(mrs.itemtype.ToString()))
615 {
616 List<mapItemReply> returnitems = new List<mapItemReply>();
617 OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()];
618 for (int i = 0; i < itemarray.Count; i++)
619 {
620 OSDMap mapitem = (OSDMap)itemarray[i];
621 mapItemReply mi = new mapItemReply();
622 mi.x = (uint)mapitem["X"].AsInteger();
623 mi.y = (uint)mapitem["Y"].AsInteger();
624 mi.id = mapitem["ID"].AsUUID();
625 mi.Extra = mapitem["Extra"].AsInteger();
626 mi.Extra2 = mapitem["Extra2"].AsInteger();
627 mi.name = mapitem["Name"].AsString();
628 returnitems.Add(mi);
629 }
630 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
631 }
632
633 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
634 uint itemtype = 7;
635
636 if (response.ContainsKey(itemtype.ToString()))
637 {
638 List<mapItemReply> returnitems = new List<mapItemReply>();
639 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
640 for (int i = 0; i < itemarray.Count; i++)
641 {
642 OSDMap mapitem = (OSDMap)itemarray[i];
643 mapItemReply mi = new mapItemReply();
644 mi.x = (uint)mapitem["X"].AsInteger();
645 mi.y = (uint)mapitem["Y"].AsInteger();
646 mi.id = mapitem["ID"].AsUUID();
647 mi.Extra = mapitem["Extra"].AsInteger();
648 mi.Extra2 = mapitem["Extra2"].AsInteger();
649 mi.name = mapitem["Name"].AsString();
650 returnitems.Add(mi);
651 }
652 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
653 }
654
655 // Service 1 (MAP_ITEM_TELEHUB)
656 itemtype = 1;
657
658 if (response.ContainsKey(itemtype.ToString()))
659 {
660 List<mapItemReply> returnitems = new List<mapItemReply>();
661 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
662 for (int i = 0; i < itemarray.Count; i++)
663 {
664 OSDMap mapitem = (OSDMap)itemarray[i];
665 mapItemReply mi = new mapItemReply();
666 mi.x = (uint)mapitem["X"].AsInteger();
667 mi.y = (uint)mapitem["Y"].AsInteger();
668 mi.id = mapitem["ID"].AsUUID();
669 mi.Extra = mapitem["Extra"].AsInteger();
670 mi.Extra2 = mapitem["Extra2"].AsInteger();
671 mi.name = mapitem["Name"].AsString();
672 returnitems.Add(mi);
673 }
674 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
675 }
676 }
677 }
678 } 626 }
679 } 627 }
680 628
@@ -701,8 +649,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
701 EnqueueMapItemRequest(st); 649 EnqueueMapItemRequest(st);
702 } 650 }
703 651
704 private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
705 uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
706 /// <summary> 652 /// <summary>
707 /// Does the actual remote mapitem request 653 /// Does the actual remote mapitem request
708 /// This should be called from an asynchronous thread 654 /// This should be called from an asynchronous thread
@@ -717,7 +663,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
717 /// <param name="itemtype">passed in from packet</param> 663 /// <param name="itemtype">passed in from packet</param>
718 /// <param name="regionhandle">Region we're looking up</param> 664 /// <param name="regionhandle">Region we're looking up</param>
719 /// <returns></returns> 665 /// <returns></returns>
720 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 666 private void RequestMapItemsAsync(UUID id, uint flags,
721 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 667 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
722 { 668 {
723// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); 669// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
@@ -740,7 +686,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
740 } 686 }
741 687
742 if (blacklisted) 688 if (blacklisted)
743 return new OSDMap(); 689 {
690 Interlocked.Decrement(ref nAsyncRequests);
691 return;
692 }
744 693
745 UUID requestID = UUID.Random(); 694 UUID requestID = UUID.Random();
746 lock (m_cachedRegionMapItemsAddress) 695 lock (m_cachedRegionMapItemsAddress)
@@ -748,6 +697,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
748 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) 697 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
749 httpserver = m_cachedRegionMapItemsAddress[regionhandle]; 698 httpserver = m_cachedRegionMapItemsAddress[regionhandle];
750 } 699 }
700
751 if (httpserver.Length == 0) 701 if (httpserver.Length == 0)
752 { 702 {
753 uint x = 0, y = 0; 703 uint x = 0, y = 0;
@@ -792,18 +742,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
792 742
793 // Can't find the http server 743 // Can't find the http server
794 if (httpserver.Length == 0 || blacklisted) 744 if (httpserver.Length == 0 || blacklisted)
795 return new OSDMap(); 745 {
796 746 Interlocked.Decrement(ref nAsyncRequests);
797 MapRequestState mrs = new MapRequestState(); 747 return;
798 mrs.agentID = id; 748 }
799 mrs.EstateID = EstateID;
800 mrs.flags = flags;
801 mrs.godlike = godlike;
802 mrs.itemtype=itemtype;
803 mrs.regionhandle = regionhandle;
804
805 lock (m_openRequests)
806 m_openRequests.Add(requestID, mrs);
807 749
808 WebRequest mapitemsrequest = null; 750 WebRequest mapitemsrequest = null;
809 try 751 try
@@ -813,7 +755,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
813 catch (Exception e) 755 catch (Exception e)
814 { 756 {
815 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); 757 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e);
816 return new OSDMap(); 758 Interlocked.Decrement(ref nAsyncRequests);
759 return;
817 } 760 }
818 761
819 mapitemsrequest.Method = "POST"; 762 mapitemsrequest.Method = "POST";
@@ -838,7 +781,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
838 catch (WebException ex) 781 catch (WebException ex)
839 { 782 {
840 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); 783 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message);
841 responseMap["connect"] = OSD.FromBoolean(false);
842 lock (m_blacklistedurls) 784 lock (m_blacklistedurls)
843 { 785 {
844 if (!m_blacklistedurls.ContainsKey(httpserver)) 786 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -847,13 +789,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
847 789
848 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 790 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
849 791
850 return responseMap; 792 Interlocked.Decrement(ref nAsyncRequests);
793 return;
851 } 794 }
852 catch 795 catch
853 { 796 {
854 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 797 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
855 responseMap["connect"] = OSD.FromBoolean(false); 798 Interlocked.Decrement(ref nAsyncRequests);
856 return responseMap; 799 return;
857 } 800 }
858 finally 801 finally
859 { 802 {
@@ -874,12 +817,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
874 } 817 }
875 else 818 else
876 { 819 {
877 return new OSDMap(); 820 Interlocked.Decrement(ref nAsyncRequests);
821 return;
878 } 822 }
879 } 823 }
880 catch (WebException) 824 catch (WebException)
881 { 825 {
882 responseMap["connect"] = OSD.FromBoolean(false);
883 lock (m_blacklistedurls) 826 lock (m_blacklistedurls)
884 { 827 {
885 if (!m_blacklistedurls.ContainsKey(httpserver)) 828 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -888,19 +831,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
888 831
889 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 832 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
890 833
891 return responseMap; 834 Interlocked.Decrement(ref nAsyncRequests);
835 return;
892 } 836 }
893 catch 837 catch
894 { 838 {
895 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 839 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
896 responseMap["connect"] = OSD.FromBoolean(false);
897 lock (m_blacklistedregions) 840 lock (m_blacklistedregions)
898 { 841 {
899 if (!m_blacklistedregions.ContainsKey(regionhandle)) 842 if (!m_blacklistedregions.ContainsKey(regionhandle))
900 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 843 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
901 } 844 }
902 845
903 return responseMap; 846 Interlocked.Decrement(ref nAsyncRequests);
847 return;
904 } 848 }
905 finally 849 finally
906 { 850 {
@@ -919,14 +863,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
919 catch (Exception ex) 863 catch (Exception ex)
920 { 864 {
921 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); 865 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message);
922 responseMap["connect"] = OSD.FromBoolean(false);
923 lock (m_blacklistedregions) 866 lock (m_blacklistedregions)
924 { 867 {
925 if (!m_blacklistedregions.ContainsKey(regionhandle)) 868 if (!m_blacklistedregions.ContainsKey(regionhandle))
926 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 869 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
927 } 870 }
928 871
929 return responseMap; 872 Interlocked.Decrement(ref nAsyncRequests);
873 return;
930 } 874 }
931 } 875 }
932 876
@@ -940,7 +884,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
940 } 884 }
941 } 885 }
942 886
943 return responseMap; 887 Interlocked.Decrement(ref nAsyncRequests);
888
889 if (id != UUID.Zero)
890 {
891 ScenePresence av = null;
892 m_scene.TryGetScenePresence(id, out av);
893 if (av != null)
894 {
895 if (responseMap.ContainsKey(itemtype.ToString()))
896 {
897 List<mapItemReply> returnitems = new List<mapItemReply>();
898 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
899 for (int i = 0; i < itemarray.Count; i++)
900 {
901 OSDMap mapitem = (OSDMap)itemarray[i];
902 mapItemReply mi = new mapItemReply();
903 mi.x = (uint)mapitem["X"].AsInteger();
904 mi.y = (uint)mapitem["Y"].AsInteger();
905 mi.id = mapitem["ID"].AsUUID();
906 mi.Extra = mapitem["Extra"].AsInteger();
907 mi.Extra2 = mapitem["Extra2"].AsInteger();
908 mi.name = mapitem["Name"].AsString();
909 returnitems.Add(mi);
910 }
911 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
912 }
913
914 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
915 itemtype = 7;
916
917 if (responseMap.ContainsKey(itemtype.ToString()))
918 {
919 List<mapItemReply> returnitems = new List<mapItemReply>();
920 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
921 for (int i = 0; i < itemarray.Count; i++)
922 {
923 OSDMap mapitem = (OSDMap)itemarray[i];
924 mapItemReply mi = new mapItemReply();
925 mi.x = (uint)mapitem["X"].AsInteger();
926 mi.y = (uint)mapitem["Y"].AsInteger();
927 mi.id = mapitem["ID"].AsUUID();
928 mi.Extra = mapitem["Extra"].AsInteger();
929 mi.Extra2 = mapitem["Extra2"].AsInteger();
930 mi.name = mapitem["Name"].AsString();
931 returnitems.Add(mi);
932 }
933 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
934 }
935
936 // Service 1 (MAP_ITEM_TELEHUB)
937 itemtype = 1;
938
939 if (responseMap.ContainsKey(itemtype.ToString()))
940 {
941 List<mapItemReply> returnitems = new List<mapItemReply>();
942 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
943 for (int i = 0; i < itemarray.Count; i++)
944 {
945 OSDMap mapitem = (OSDMap)itemarray[i];
946 mapItemReply mi = new mapItemReply();
947 mi.x = (uint)mapitem["X"].AsInteger();
948 mi.y = (uint)mapitem["Y"].AsInteger();
949 mi.id = mapitem["ID"].AsUUID();
950 mi.Extra = mapitem["Extra"].AsInteger();
951 mi.Extra2 = mapitem["Extra2"].AsInteger();
952 mi.name = mapitem["Name"].AsString();
953 returnitems.Add(mi);
954 }
955 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
956 }
957 }
958 }
944 } 959 }
945 960
946 /// <summary> 961 /// <summary>
@@ -950,7 +965,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
950 /// <param name="minY"></param> 965 /// <param name="minY"></param>
951 /// <param name="maxX"></param> 966 /// <param name="maxX"></param>
952 /// <param name="maxY"></param> 967 /// <param name="maxY"></param>
953 public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 968 public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
954 { 969 {
955 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); 970 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
956 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible 971 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible
@@ -1003,21 +1018,91 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1003 1018
1004 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 1019 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1005 { 1020 {
1021 MapBlockRequestData req = new MapBlockRequestData();
1022
1023 req.client = remoteClient;
1024 req.minX = minX;
1025 req.maxX = maxX;
1026 req.minY = minY;
1027 req.maxY = maxY;
1028 req.flags = flag;
1029
1030 lock (m_mapBlockRequestEvent)
1031 {
1032 if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId))
1033 m_mapBlockRequests[remoteClient.AgentId] = new Queue<MapBlockRequestData>();
1034 m_mapBlockRequests[remoteClient.AgentId].Enqueue(req);
1035 m_mapBlockRequestEvent.Set();
1036 }
1037
1038 return new List<MapBlockData>();
1039 }
1040
1041 protected void MapBlockSendThread()
1042 {
1043 while (true)
1044 {
1045 List<MapBlockRequestData> thisRunData = new List<MapBlockRequestData>();
1046
1047 m_mapBlockRequestEvent.WaitOne();
1048 lock (m_mapBlockRequestEvent)
1049 {
1050 int total = 0;
1051 foreach (Queue<MapBlockRequestData> q in m_mapBlockRequests.Values)
1052 {
1053 if (q.Count > 0)
1054 thisRunData.Add(q.Dequeue());
1055
1056 total += q.Count;
1057 }
1058
1059 if (total == 0)
1060 m_mapBlockRequestEvent.Reset();
1061 }
1062
1063 foreach (MapBlockRequestData req in thisRunData)
1064 {
1065 // Null client stops thread
1066 if (req.client == null)
1067 return;
1068
1069 GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags);
1070 }
1071
1072 Thread.Sleep(50);
1073 }
1074 }
1075
1076 protected virtual List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1077 {
1078 List<MapBlockData> allBlocks = new List<MapBlockData>();
1006 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1079 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1007 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1080 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1008 (minX - 4) * (int)Constants.RegionSize, 1081 minX * (int)Constants.RegionSize,
1009 (maxX + 4) * (int)Constants.RegionSize, 1082 maxX * (int)Constants.RegionSize,
1010 (minY - 4) * (int)Constants.RegionSize, 1083 minY * (int)Constants.RegionSize,
1011 (maxY + 4) * (int)Constants.RegionSize); 1084 maxY * (int)Constants.RegionSize);
1085// (minX - 4) * (int)Constants.RegionSize,
1086// (maxX + 4) * (int)Constants.RegionSize,
1087// (minY - 4) * (int)Constants.RegionSize,
1088// (maxY + 4) * (int)Constants.RegionSize);
1012 foreach (GridRegion r in regions) 1089 foreach (GridRegion r in regions)
1013 { 1090 {
1014 MapBlockData block = new MapBlockData(); 1091 MapBlockData block = new MapBlockData();
1015 MapBlockFromGridRegion(block, r, flag); 1092 MapBlockFromGridRegion(block, r, flag);
1016 mapBlocks.Add(block); 1093 mapBlocks.Add(block);
1094 allBlocks.Add(block);
1095 if (mapBlocks.Count >= 10)
1096 {
1097 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1098 mapBlocks.Clear();
1099 Thread.Sleep(50);
1100 }
1017 } 1101 }
1018 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); 1102 if (mapBlocks.Count > 0)
1103 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1019 1104
1020 return mapBlocks; 1105 return allBlocks;
1021 } 1106 }
1022 1107
1023 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) 1108 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag)
@@ -1417,6 +1502,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1417 { 1502 {
1418 m_rootAgents.Remove(avatar.UUID); 1503 m_rootAgents.Remove(avatar.UUID);
1419 } 1504 }
1505
1506 lock (m_mapBlockRequestEvent)
1507 {
1508 if (m_mapBlockRequests.ContainsKey(avatar.UUID))
1509 m_mapBlockRequests.Remove(avatar.UUID);
1510 }
1420 } 1511 }
1421 1512
1422 public void OnRegionUp(GridRegion otherRegion) 1513 public void OnRegionUp(GridRegion otherRegion)
@@ -1540,4 +1631,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1540 public uint itemtype; 1631 public uint itemtype;
1541 public ulong regionhandle; 1632 public ulong regionhandle;
1542 } 1633 }
1634
1635 public struct MapBlockRequestData
1636 {
1637 public IClientAPI client;
1638 public int minX;
1639 public int minY;
1640 public int maxX;
1641 public int maxY;
1642 public uint flags;
1643 }
1543} 1644}