diff options
6 files changed, 416 insertions, 289 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 899e5ea..a226b78 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>(); |
@@ -227,54 +230,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
227 | // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is | 230 | // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is |
228 | // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. | 231 | // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. |
229 | 232 | ||
230 | if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) | 233 | //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) |
231 | { | 234 | //{ |
232 | ScenePresence avatarPresence = null; | 235 | // ScenePresence avatarPresence = null; |
233 | 236 | ||
234 | m_scene.TryGetScenePresence(agentID, out avatarPresence); | 237 | // m_scene.TryGetScenePresence(agentID, out avatarPresence); |
235 | 238 | ||
236 | if (avatarPresence != null) | 239 | // if (avatarPresence != null) |
237 | { | 240 | // { |
238 | bool lookup = false; | 241 | // bool lookup = false; |
239 | 242 | ||
240 | lock (cachedMapBlocks) | 243 | // lock (cachedMapBlocks) |
241 | { | 244 | // { |
242 | if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) | 245 | // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) |
243 | { | 246 | // { |
244 | List<MapBlockData> mapBlocks; | 247 | // List<MapBlockData> mapBlocks; |
245 | 248 | ||
246 | mapBlocks = cachedMapBlocks; | 249 | // mapBlocks = cachedMapBlocks; |
247 | avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); | 250 | // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); |
248 | } | 251 | // } |
249 | else | 252 | // else |
250 | { | 253 | // { |
251 | lookup = true; | 254 | // lookup = true; |
252 | } | 255 | // } |
253 | } | 256 | // } |
254 | if (lookup) | 257 | // if (lookup) |
255 | { | 258 | // { |
256 | List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; | 259 | // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; |
257 | 260 | ||
258 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, | 261 | // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, |
259 | (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, | 262 | // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, |
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.RegionLocY - 8) * (int)Constants.RegionSize, | 264 | // (int)(m_scene.RegionInfo.RegionLocY - 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 | foreach (GridRegion r in regions) | 266 | // foreach (GridRegion r in regions) |
264 | { | 267 | // { |
265 | MapBlockData block = new MapBlockData(); | 268 | // MapBlockData block = new MapBlockData(); |
266 | MapBlockFromGridRegion(block, r, 0); | 269 | // MapBlockFromGridRegion(block, r, 0); |
267 | mapBlocks.Add(block); | 270 | // mapBlocks.Add(block); |
268 | } | 271 | // } |
269 | avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); | 272 | // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); |
270 | 273 | ||
271 | lock (cachedMapBlocks) | 274 | // lock (cachedMapBlocks) |
272 | cachedMapBlocks = mapBlocks; | 275 | // cachedMapBlocks = mapBlocks; |
273 | 276 | ||
274 | cachedTime = Util.UnixTimeSinceEpoch(); | 277 | // cachedTime = Util.UnixTimeSinceEpoch(); |
275 | } | 278 | // } |
276 | } | 279 | // } |
277 | } | 280 | //} |
278 | 281 | ||
279 | LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); | 282 | LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); |
280 | mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); | 283 | mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); |
@@ -301,8 +304,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
301 | protected static OSDMapLayer GetOSDMapLayerResponse() | 304 | protected static OSDMapLayer GetOSDMapLayerResponse() |
302 | { | 305 | { |
303 | OSDMapLayer mapLayer = new OSDMapLayer(); | 306 | OSDMapLayer mapLayer = new OSDMapLayer(); |
304 | mapLayer.Right = 5000; | 307 | mapLayer.Right = 2048; |
305 | mapLayer.Top = 5000; | 308 | mapLayer.Top = 2048; |
306 | mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); | 309 | mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); |
307 | 310 | ||
308 | return mapLayer; | 311 | return mapLayer; |
@@ -331,6 +334,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
331 | { | 334 | { |
332 | m_rootAgents.Remove(AgentId); | 335 | m_rootAgents.Remove(AgentId); |
333 | } | 336 | } |
337 | lock (m_mapBlockRequestEvent) | ||
338 | { | ||
339 | if (m_mapBlockRequests.ContainsKey(AgentId)) | ||
340 | m_mapBlockRequests.Remove(AgentId); | ||
341 | } | ||
334 | } | 342 | } |
335 | #endregion | 343 | #endregion |
336 | 344 | ||
@@ -353,6 +361,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
353 | ThreadPriority.BelowNormal, | 361 | ThreadPriority.BelowNormal, |
354 | true, | 362 | true, |
355 | true); | 363 | true); |
364 | Watchdog.StartThread( | ||
365 | MapBlockSendThread, | ||
366 | string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName), | ||
367 | ThreadPriority.BelowNormal, | ||
368 | true, | ||
369 | true); | ||
356 | } | 370 | } |
357 | 371 | ||
358 | /// <summary> | 372 | /// <summary> |
@@ -368,7 +382,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
368 | st.itemtype=0; | 382 | st.itemtype=0; |
369 | st.regionhandle=0; | 383 | st.regionhandle=0; |
370 | 384 | ||
371 | requests.Enqueue(st); | 385 | lock (requests) |
386 | { | ||
387 | queueEvent.Set(); | ||
388 | requests.Enqueue(st); | ||
389 | } | ||
390 | |||
391 | MapBlockRequestData req = new MapBlockRequestData(); | ||
392 | |||
393 | req.client = null; | ||
394 | req.minX = 0; | ||
395 | req.maxX = 0; | ||
396 | req.minY = 0; | ||
397 | req.maxY = 0; | ||
398 | req.flags = 0; | ||
399 | |||
400 | lock (m_mapBlockRequestEvent) | ||
401 | { | ||
402 | m_mapBlockRequests[UUID.Zero] = new Queue<MapBlockRequestData>(); | ||
403 | m_mapBlockRequests[UUID.Zero].Enqueue(req); | ||
404 | m_mapBlockRequestEvent.Set(); | ||
405 | } | ||
372 | } | 406 | } |
373 | 407 | ||
374 | public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, | 408 | public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, |
@@ -519,12 +553,26 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
519 | /// </summary> | 553 | /// </summary> |
520 | public void process() | 554 | public void process() |
521 | { | 555 | { |
522 | const int MAX_ASYNC_REQUESTS = 20; | 556 | const int MAX_ASYNC_REQUESTS = 5; |
523 | try | 557 | try |
524 | { | 558 | { |
525 | while (true) | 559 | while (true) |
526 | { | 560 | { |
527 | MapRequestState st = requests.Dequeue(1000); | 561 | MapRequestState st = new MapRequestState(); |
562 | bool valid = false; | ||
563 | queueEvent.WaitOne(); | ||
564 | lock (requests) | ||
565 | { | ||
566 | if (requests.Count > 0) | ||
567 | { | ||
568 | st = requests.Dequeue(); | ||
569 | valid = true; | ||
570 | } | ||
571 | if (requests.Count == 0) | ||
572 | queueEvent.Reset(); | ||
573 | } | ||
574 | if (!valid) | ||
575 | continue; | ||
528 | 576 | ||
529 | // end gracefully | 577 | // end gracefully |
530 | if (st.agentID == STOP_UUID) | 578 | if (st.agentID == STOP_UUID) |
@@ -541,14 +589,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
541 | 589 | ||
542 | if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) | 590 | if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) |
543 | { | 591 | { |
544 | while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break | 592 | // while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break |
545 | Thread.Sleep(80); | 593 | // Thread.Sleep(500); |
546 | 594 | ||
547 | RequestMapItemsDelegate d = RequestMapItemsAsync; | ||
548 | d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null); | ||
549 | //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); | ||
550 | //RequestMapItemsCompleted(response); | ||
551 | Interlocked.Increment(ref nAsyncRequests); | 595 | Interlocked.Increment(ref nAsyncRequests); |
596 | RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); | ||
552 | } | 597 | } |
553 | } | 598 | } |
554 | 599 | ||
@@ -570,110 +615,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
570 | /// <param name="state"></param> | 615 | /// <param name="state"></param> |
571 | public void EnqueueMapItemRequest(MapRequestState state) | 616 | public void EnqueueMapItemRequest(MapRequestState state) |
572 | { | 617 | { |
573 | requests.Enqueue(state); | 618 | lock (requests) |
574 | } | ||
575 | |||
576 | /// <summary> | ||
577 | /// Sends the mapitem response to the IClientAPI | ||
578 | /// </summary> | ||
579 | /// <param name="response">The OSDMap Response for the mapitem</param> | ||
580 | private void RequestMapItemsCompleted(IAsyncResult iar) | ||
581 | { | ||
582 | AsyncResult result = (AsyncResult)iar; | ||
583 | RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate; | ||
584 | |||
585 | OSDMap response = (OSDMap)icon.EndInvoke(iar); | ||
586 | |||
587 | Interlocked.Decrement(ref nAsyncRequests); | ||
588 | |||
589 | if (!response.ContainsKey("requestID")) | ||
590 | return; | ||
591 | |||
592 | UUID requestID = response["requestID"].AsUUID(); | ||
593 | |||
594 | if (requestID != UUID.Zero) | ||
595 | { | 619 | { |
596 | MapRequestState mrs = new MapRequestState(); | 620 | queueEvent.Set(); |
597 | mrs.agentID = UUID.Zero; | 621 | requests.Enqueue(state); |
598 | lock (m_openRequests) | ||
599 | { | ||
600 | if (m_openRequests.ContainsKey(requestID)) | ||
601 | { | ||
602 | mrs = m_openRequests[requestID]; | ||
603 | m_openRequests.Remove(requestID); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | if (mrs.agentID != UUID.Zero) | ||
608 | { | ||
609 | ScenePresence av = null; | ||
610 | m_scene.TryGetScenePresence(mrs.agentID, out av); | ||
611 | if (av != null) | ||
612 | { | ||
613 | if (response.ContainsKey(mrs.itemtype.ToString())) | ||
614 | { | ||
615 | List<mapItemReply> returnitems = new List<mapItemReply>(); | ||
616 | OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()]; | ||
617 | for (int i = 0; i < itemarray.Count; i++) | ||
618 | { | ||
619 | OSDMap mapitem = (OSDMap)itemarray[i]; | ||
620 | mapItemReply mi = new mapItemReply(); | ||
621 | mi.x = (uint)mapitem["X"].AsInteger(); | ||
622 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
623 | mi.id = mapitem["ID"].AsUUID(); | ||
624 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
625 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
626 | mi.name = mapitem["Name"].AsString(); | ||
627 | returnitems.Add(mi); | ||
628 | } | ||
629 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); | ||
630 | } | ||
631 | |||
632 | // Service 7 (MAP_ITEM_LAND_FOR_SALE) | ||
633 | uint itemtype = 7; | ||
634 | |||
635 | if (response.ContainsKey(itemtype.ToString())) | ||
636 | { | ||
637 | List<mapItemReply> returnitems = new List<mapItemReply>(); | ||
638 | OSDArray itemarray = (OSDArray)response[itemtype.ToString()]; | ||
639 | for (int i = 0; i < itemarray.Count; i++) | ||
640 | { | ||
641 | OSDMap mapitem = (OSDMap)itemarray[i]; | ||
642 | mapItemReply mi = new mapItemReply(); | ||
643 | mi.x = (uint)mapitem["X"].AsInteger(); | ||
644 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
645 | mi.id = mapitem["ID"].AsUUID(); | ||
646 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
647 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
648 | mi.name = mapitem["Name"].AsString(); | ||
649 | returnitems.Add(mi); | ||
650 | } | ||
651 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); | ||
652 | } | ||
653 | |||
654 | // Service 1 (MAP_ITEM_TELEHUB) | ||
655 | itemtype = 1; | ||
656 | |||
657 | if (response.ContainsKey(itemtype.ToString())) | ||
658 | { | ||
659 | List<mapItemReply> returnitems = new List<mapItemReply>(); | ||
660 | OSDArray itemarray = (OSDArray)response[itemtype.ToString()]; | ||
661 | for (int i = 0; i < itemarray.Count; i++) | ||
662 | { | ||
663 | OSDMap mapitem = (OSDMap)itemarray[i]; | ||
664 | mapItemReply mi = new mapItemReply(); | ||
665 | mi.x = (uint)mapitem["X"].AsInteger(); | ||
666 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
667 | mi.id = mapitem["ID"].AsUUID(); | ||
668 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
669 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
670 | mi.name = mapitem["Name"].AsString(); | ||
671 | returnitems.Add(mi); | ||
672 | } | ||
673 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); | ||
674 | } | ||
675 | } | ||
676 | } | ||
677 | } | 622 | } |
678 | } | 623 | } |
679 | 624 | ||
@@ -700,8 +645,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
700 | EnqueueMapItemRequest(st); | 645 | EnqueueMapItemRequest(st); |
701 | } | 646 | } |
702 | 647 | ||
703 | private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags, | ||
704 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle); | ||
705 | /// <summary> | 648 | /// <summary> |
706 | /// Does the actual remote mapitem request | 649 | /// Does the actual remote mapitem request |
707 | /// This should be called from an asynchronous thread | 650 | /// This should be called from an asynchronous thread |
@@ -716,7 +659,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
716 | /// <param name="itemtype">passed in from packet</param> | 659 | /// <param name="itemtype">passed in from packet</param> |
717 | /// <param name="regionhandle">Region we're looking up</param> | 660 | /// <param name="regionhandle">Region we're looking up</param> |
718 | /// <returns></returns> | 661 | /// <returns></returns> |
719 | private OSDMap RequestMapItemsAsync(UUID id, uint flags, | 662 | private void RequestMapItemsAsync(UUID id, uint flags, |
720 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle) | 663 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle) |
721 | { | 664 | { |
722 | // m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); | 665 | // m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); |
@@ -739,7 +682,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
739 | } | 682 | } |
740 | 683 | ||
741 | if (blacklisted) | 684 | if (blacklisted) |
742 | return new OSDMap(); | 685 | { |
686 | Interlocked.Decrement(ref nAsyncRequests); | ||
687 | return; | ||
688 | } | ||
743 | 689 | ||
744 | UUID requestID = UUID.Random(); | 690 | UUID requestID = UUID.Random(); |
745 | lock (m_cachedRegionMapItemsAddress) | 691 | lock (m_cachedRegionMapItemsAddress) |
@@ -747,6 +693,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
747 | if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) | 693 | if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) |
748 | httpserver = m_cachedRegionMapItemsAddress[regionhandle]; | 694 | httpserver = m_cachedRegionMapItemsAddress[regionhandle]; |
749 | } | 695 | } |
696 | |||
750 | if (httpserver.Length == 0) | 697 | if (httpserver.Length == 0) |
751 | { | 698 | { |
752 | uint x = 0, y = 0; | 699 | uint x = 0, y = 0; |
@@ -791,18 +738,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
791 | 738 | ||
792 | // Can't find the http server | 739 | // Can't find the http server |
793 | if (httpserver.Length == 0 || blacklisted) | 740 | if (httpserver.Length == 0 || blacklisted) |
794 | return new OSDMap(); | 741 | { |
795 | 742 | Interlocked.Decrement(ref nAsyncRequests); | |
796 | MapRequestState mrs = new MapRequestState(); | 743 | return; |
797 | mrs.agentID = id; | 744 | } |
798 | mrs.EstateID = EstateID; | ||
799 | mrs.flags = flags; | ||
800 | mrs.godlike = godlike; | ||
801 | mrs.itemtype=itemtype; | ||
802 | mrs.regionhandle = regionhandle; | ||
803 | |||
804 | lock (m_openRequests) | ||
805 | m_openRequests.Add(requestID, mrs); | ||
806 | 745 | ||
807 | WebRequest mapitemsrequest = null; | 746 | WebRequest mapitemsrequest = null; |
808 | try | 747 | try |
@@ -812,7 +751,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
812 | catch (Exception e) | 751 | catch (Exception e) |
813 | { | 752 | { |
814 | m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); | 753 | m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); |
815 | return new OSDMap(); | 754 | Interlocked.Decrement(ref nAsyncRequests); |
755 | return; | ||
816 | } | 756 | } |
817 | 757 | ||
818 | mapitemsrequest.Method = "POST"; | 758 | mapitemsrequest.Method = "POST"; |
@@ -826,6 +766,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
826 | OSDMap responseMap = new OSDMap(); | 766 | OSDMap responseMap = new OSDMap(); |
827 | responseMap["requestID"] = OSD.FromUUID(requestID); | 767 | responseMap["requestID"] = OSD.FromUUID(requestID); |
828 | 768 | ||
769 | return; | ||
829 | Stream os = null; | 770 | Stream os = null; |
830 | try | 771 | try |
831 | { // send the Post | 772 | { // send the Post |
@@ -837,7 +778,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
837 | catch (WebException ex) | 778 | catch (WebException ex) |
838 | { | 779 | { |
839 | m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); | 780 | m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); |
840 | responseMap["connect"] = OSD.FromBoolean(false); | ||
841 | lock (m_blacklistedurls) | 781 | lock (m_blacklistedurls) |
842 | { | 782 | { |
843 | if (!m_blacklistedurls.ContainsKey(httpserver)) | 783 | if (!m_blacklistedurls.ContainsKey(httpserver)) |
@@ -846,13 +786,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
846 | 786 | ||
847 | m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); | 787 | m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); |
848 | 788 | ||
849 | return responseMap; | 789 | Interlocked.Decrement(ref nAsyncRequests); |
790 | return; | ||
850 | } | 791 | } |
851 | catch | 792 | catch |
852 | { | 793 | { |
853 | m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); | 794 | m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); |
854 | responseMap["connect"] = OSD.FromBoolean(false); | 795 | Interlocked.Decrement(ref nAsyncRequests); |
855 | return responseMap; | 796 | return; |
856 | } | 797 | } |
857 | finally | 798 | finally |
858 | { | 799 | { |
@@ -873,12 +814,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
873 | } | 814 | } |
874 | else | 815 | else |
875 | { | 816 | { |
876 | return new OSDMap(); | 817 | Interlocked.Decrement(ref nAsyncRequests); |
818 | return; | ||
877 | } | 819 | } |
878 | } | 820 | } |
879 | catch (WebException) | 821 | catch (WebException) |
880 | { | 822 | { |
881 | responseMap["connect"] = OSD.FromBoolean(false); | ||
882 | lock (m_blacklistedurls) | 823 | lock (m_blacklistedurls) |
883 | { | 824 | { |
884 | if (!m_blacklistedurls.ContainsKey(httpserver)) | 825 | if (!m_blacklistedurls.ContainsKey(httpserver)) |
@@ -887,19 +828,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
887 | 828 | ||
888 | m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); | 829 | m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); |
889 | 830 | ||
890 | return responseMap; | 831 | Interlocked.Decrement(ref nAsyncRequests); |
832 | return; | ||
891 | } | 833 | } |
892 | catch | 834 | catch |
893 | { | 835 | { |
894 | m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); | 836 | m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); |
895 | responseMap["connect"] = OSD.FromBoolean(false); | ||
896 | lock (m_blacklistedregions) | 837 | lock (m_blacklistedregions) |
897 | { | 838 | { |
898 | if (!m_blacklistedregions.ContainsKey(regionhandle)) | 839 | if (!m_blacklistedregions.ContainsKey(regionhandle)) |
899 | m_blacklistedregions.Add(regionhandle, Environment.TickCount); | 840 | m_blacklistedregions.Add(regionhandle, Environment.TickCount); |
900 | } | 841 | } |
901 | 842 | ||
902 | return responseMap; | 843 | Interlocked.Decrement(ref nAsyncRequests); |
844 | return; | ||
903 | } | 845 | } |
904 | finally | 846 | finally |
905 | { | 847 | { |
@@ -918,14 +860,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
918 | catch (Exception ex) | 860 | catch (Exception ex) |
919 | { | 861 | { |
920 | m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); | 862 | m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); |
921 | responseMap["connect"] = OSD.FromBoolean(false); | ||
922 | lock (m_blacklistedregions) | 863 | lock (m_blacklistedregions) |
923 | { | 864 | { |
924 | if (!m_blacklistedregions.ContainsKey(regionhandle)) | 865 | if (!m_blacklistedregions.ContainsKey(regionhandle)) |
925 | m_blacklistedregions.Add(regionhandle, Environment.TickCount); | 866 | m_blacklistedregions.Add(regionhandle, Environment.TickCount); |
926 | } | 867 | } |
927 | 868 | ||
928 | return responseMap; | 869 | Interlocked.Decrement(ref nAsyncRequests); |
870 | return; | ||
929 | } | 871 | } |
930 | } | 872 | } |
931 | 873 | ||
@@ -939,7 +881,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
939 | } | 881 | } |
940 | } | 882 | } |
941 | 883 | ||
942 | return responseMap; | 884 | Interlocked.Decrement(ref nAsyncRequests); |
885 | |||
886 | if (id != UUID.Zero) | ||
887 | { | ||
888 | ScenePresence av = null; | ||
889 | m_scene.TryGetScenePresence(id, out av); | ||
890 | if (av != null) | ||
891 | { | ||
892 | if (responseMap.ContainsKey(itemtype.ToString())) | ||
893 | { | ||
894 | List<mapItemReply> returnitems = new List<mapItemReply>(); | ||
895 | OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()]; | ||
896 | for (int i = 0; i < itemarray.Count; i++) | ||
897 | { | ||
898 | OSDMap mapitem = (OSDMap)itemarray[i]; | ||
899 | mapItemReply mi = new mapItemReply(); | ||
900 | mi.x = (uint)mapitem["X"].AsInteger(); | ||
901 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
902 | mi.id = mapitem["ID"].AsUUID(); | ||
903 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
904 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
905 | mi.name = mapitem["Name"].AsString(); | ||
906 | returnitems.Add(mi); | ||
907 | } | ||
908 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags); | ||
909 | } | ||
910 | |||
911 | // Service 7 (MAP_ITEM_LAND_FOR_SALE) | ||
912 | itemtype = 7; | ||
913 | |||
914 | if (responseMap.ContainsKey(itemtype.ToString())) | ||
915 | { | ||
916 | List<mapItemReply> returnitems = new List<mapItemReply>(); | ||
917 | OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()]; | ||
918 | for (int i = 0; i < itemarray.Count; i++) | ||
919 | { | ||
920 | OSDMap mapitem = (OSDMap)itemarray[i]; | ||
921 | mapItemReply mi = new mapItemReply(); | ||
922 | mi.x = (uint)mapitem["X"].AsInteger(); | ||
923 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
924 | mi.id = mapitem["ID"].AsUUID(); | ||
925 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
926 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
927 | mi.name = mapitem["Name"].AsString(); | ||
928 | returnitems.Add(mi); | ||
929 | } | ||
930 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags); | ||
931 | } | ||
932 | |||
933 | // Service 1 (MAP_ITEM_TELEHUB) | ||
934 | itemtype = 1; | ||
935 | |||
936 | if (responseMap.ContainsKey(itemtype.ToString())) | ||
937 | { | ||
938 | List<mapItemReply> returnitems = new List<mapItemReply>(); | ||
939 | OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()]; | ||
940 | for (int i = 0; i < itemarray.Count; i++) | ||
941 | { | ||
942 | OSDMap mapitem = (OSDMap)itemarray[i]; | ||
943 | mapItemReply mi = new mapItemReply(); | ||
944 | mi.x = (uint)mapitem["X"].AsInteger(); | ||
945 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
946 | mi.id = mapitem["ID"].AsUUID(); | ||
947 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
948 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
949 | mi.name = mapitem["Name"].AsString(); | ||
950 | returnitems.Add(mi); | ||
951 | } | ||
952 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags); | ||
953 | } | ||
954 | } | ||
955 | } | ||
943 | } | 956 | } |
944 | 957 | ||
945 | /// <summary> | 958 | /// <summary> |
@@ -949,7 +962,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
949 | /// <param name="minY"></param> | 962 | /// <param name="minY"></param> |
950 | /// <param name="maxX"></param> | 963 | /// <param name="maxX"></param> |
951 | /// <param name="maxY"></param> | 964 | /// <param name="maxY"></param> |
952 | public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) | 965 | public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) |
953 | { | 966 | { |
954 | //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); | 967 | //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); |
955 | if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible | 968 | if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible |
@@ -1002,21 +1015,91 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1002 | 1015 | ||
1003 | protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) | 1016 | protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) |
1004 | { | 1017 | { |
1018 | MapBlockRequestData req = new MapBlockRequestData(); | ||
1019 | |||
1020 | req.client = remoteClient; | ||
1021 | req.minX = minX; | ||
1022 | req.maxX = maxX; | ||
1023 | req.minY = minY; | ||
1024 | req.maxY = maxY; | ||
1025 | req.flags = flag; | ||
1026 | |||
1027 | lock (m_mapBlockRequestEvent) | ||
1028 | { | ||
1029 | if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId)) | ||
1030 | m_mapBlockRequests[remoteClient.AgentId] = new Queue<MapBlockRequestData>(); | ||
1031 | m_mapBlockRequests[remoteClient.AgentId].Enqueue(req); | ||
1032 | m_mapBlockRequestEvent.Set(); | ||
1033 | } | ||
1034 | |||
1035 | return new List<MapBlockData>(); | ||
1036 | } | ||
1037 | |||
1038 | protected void MapBlockSendThread() | ||
1039 | { | ||
1040 | while (true) | ||
1041 | { | ||
1042 | List<MapBlockRequestData> thisRunData = new List<MapBlockRequestData>(); | ||
1043 | |||
1044 | m_mapBlockRequestEvent.WaitOne(); | ||
1045 | lock (m_mapBlockRequestEvent) | ||
1046 | { | ||
1047 | int total = 0; | ||
1048 | foreach (Queue<MapBlockRequestData> q in m_mapBlockRequests.Values) | ||
1049 | { | ||
1050 | if (q.Count > 0) | ||
1051 | thisRunData.Add(q.Dequeue()); | ||
1052 | |||
1053 | total += q.Count; | ||
1054 | } | ||
1055 | |||
1056 | if (total == 0) | ||
1057 | m_mapBlockRequestEvent.Reset(); | ||
1058 | } | ||
1059 | |||
1060 | foreach (MapBlockRequestData req in thisRunData) | ||
1061 | { | ||
1062 | // Null client stops thread | ||
1063 | if (req.client == null) | ||
1064 | return; | ||
1065 | |||
1066 | GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags); | ||
1067 | } | ||
1068 | |||
1069 | Thread.Sleep(50); | ||
1070 | } | ||
1071 | } | ||
1072 | |||
1073 | protected virtual List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) | ||
1074 | { | ||
1075 | List<MapBlockData> allBlocks = new List<MapBlockData>(); | ||
1005 | List<MapBlockData> mapBlocks = new List<MapBlockData>(); | 1076 | List<MapBlockData> mapBlocks = new List<MapBlockData>(); |
1006 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, | 1077 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, |
1007 | (minX - 4) * (int)Constants.RegionSize, | 1078 | minX * (int)Constants.RegionSize, |
1008 | (maxX + 4) * (int)Constants.RegionSize, | 1079 | maxX * (int)Constants.RegionSize, |
1009 | (minY - 4) * (int)Constants.RegionSize, | 1080 | minY * (int)Constants.RegionSize, |
1010 | (maxY + 4) * (int)Constants.RegionSize); | 1081 | maxY * (int)Constants.RegionSize); |
1082 | // (minX - 4) * (int)Constants.RegionSize, | ||
1083 | // (maxX + 4) * (int)Constants.RegionSize, | ||
1084 | // (minY - 4) * (int)Constants.RegionSize, | ||
1085 | // (maxY + 4) * (int)Constants.RegionSize); | ||
1011 | foreach (GridRegion r in regions) | 1086 | foreach (GridRegion r in regions) |
1012 | { | 1087 | { |
1013 | MapBlockData block = new MapBlockData(); | 1088 | MapBlockData block = new MapBlockData(); |
1014 | MapBlockFromGridRegion(block, r, flag); | 1089 | MapBlockFromGridRegion(block, r, flag); |
1015 | mapBlocks.Add(block); | 1090 | mapBlocks.Add(block); |
1091 | allBlocks.Add(block); | ||
1092 | if (mapBlocks.Count >= 10) | ||
1093 | { | ||
1094 | remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); | ||
1095 | mapBlocks.Clear(); | ||
1096 | Thread.Sleep(50); | ||
1097 | } | ||
1016 | } | 1098 | } |
1017 | remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); | 1099 | if (mapBlocks.Count > 0) |
1100 | remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); | ||
1018 | 1101 | ||
1019 | return mapBlocks; | 1102 | return allBlocks; |
1020 | } | 1103 | } |
1021 | 1104 | ||
1022 | protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) | 1105 | protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) |
@@ -1415,6 +1498,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1415 | { | 1498 | { |
1416 | m_rootAgents.Remove(avatar.UUID); | 1499 | m_rootAgents.Remove(avatar.UUID); |
1417 | } | 1500 | } |
1501 | |||
1502 | lock (m_mapBlockRequestEvent) | ||
1503 | { | ||
1504 | if (m_mapBlockRequests.ContainsKey(avatar.UUID)) | ||
1505 | m_mapBlockRequests.Remove(avatar.UUID); | ||
1506 | } | ||
1418 | } | 1507 | } |
1419 | 1508 | ||
1420 | public void OnRegionUp(GridRegion otherRegion) | 1509 | public void OnRegionUp(GridRegion otherRegion) |
@@ -1538,4 +1627,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1538 | public uint itemtype; | 1627 | public uint itemtype; |
1539 | public ulong regionhandle; | 1628 | public ulong regionhandle; |
1540 | } | 1629 | } |
1630 | |||
1631 | public struct MapBlockRequestData | ||
1632 | { | ||
1633 | public IClientAPI client; | ||
1634 | public int minX; | ||
1635 | public int minY; | ||
1636 | public int maxX; | ||
1637 | public int maxY; | ||
1638 | public uint flags; | ||
1639 | } | ||
1541 | } | 1640 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs index e2ef77b..41e8944 100644 --- a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs +++ b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs | |||
@@ -599,7 +599,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
599 | return v; | 599 | return v; |
600 | } | 600 | } |
601 | 601 | ||
602 | public void FromXml2(XmlTextReader _reader, out bool errors) | 602 | public static SOPVehicle FromXml2(XmlTextReader reader) |
603 | { | ||
604 | SOPVehicle vehicle = new SOPVehicle(); | ||
605 | |||
606 | bool errors = false; | ||
607 | |||
608 | vehicle.FromXml2(reader, out errors); | ||
609 | if (errors) | ||
610 | return null; | ||
611 | |||
612 | return vehicle; | ||
613 | } | ||
614 | |||
615 | private void FromXml2(XmlTextReader _reader, out bool errors) | ||
603 | { | 616 | { |
604 | errors = false; | 617 | errors = false; |
605 | reader = _reader; | 618 | reader = _reader; |
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index c7e4c3e..abca14f 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | |||
@@ -623,12 +623,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
623 | 623 | ||
624 | private static void ProcessVehicle(SceneObjectPart obj, XmlTextReader reader) | 624 | private static void ProcessVehicle(SceneObjectPart obj, XmlTextReader reader) |
625 | { | 625 | { |
626 | bool errors = false; | 626 | SOPVehicle vehicle = SOPVehicle.FromXml2(reader); |
627 | SOPVehicle _vehicle = new SOPVehicle(); | ||
628 | 627 | ||
629 | _vehicle.FromXml2(reader, out errors); | 628 | if (vehicle == null) |
630 | |||
631 | if (errors) | ||
632 | { | 629 | { |
633 | obj.VehicleParams = null; | 630 | obj.VehicleParams = null; |
634 | m_log.DebugFormat( | 631 | m_log.DebugFormat( |
@@ -636,7 +633,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
636 | obj.Name, obj.UUID); | 633 | obj.Name, obj.UUID); |
637 | } | 634 | } |
638 | else | 635 | else |
639 | obj.VehicleParams = _vehicle; | 636 | { |
637 | obj.VehicleParams = vehicle; | ||
638 | } | ||
640 | } | 639 | } |
641 | 640 | ||
642 | private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) | 641 | private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) |
diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs index fb85d1c..4502b7d 100644 --- a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs | |||
@@ -29,6 +29,7 @@ using System; | |||
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Net; | 30 | using System.Net; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Threading; | ||
32 | 33 | ||
33 | using Nini.Config; | 34 | using Nini.Config; |
34 | using log4net; | 35 | using log4net; |
@@ -70,6 +71,8 @@ namespace OpenSim.Server.Handlers.MapImage | |||
70 | 71 | ||
71 | class MapServerGetHandler : BaseStreamHandler | 72 | class MapServerGetHandler : BaseStreamHandler |
72 | { | 73 | { |
74 | public static ManualResetEvent ev = new ManualResetEvent(true); | ||
75 | |||
73 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 76 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
74 | 77 | ||
75 | private IMapImageService m_MapService; | 78 | private IMapImageService m_MapService; |
@@ -82,8 +85,13 @@ namespace OpenSim.Server.Handlers.MapImage | |||
82 | 85 | ||
83 | public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | 86 | public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) |
84 | { | 87 | { |
85 | byte[] result = new byte[0]; | 88 | ev.WaitOne(); |
89 | lock (ev) | ||
90 | { | ||
91 | ev.Reset(); | ||
92 | } | ||
86 | 93 | ||
94 | byte[] result = new byte[0]; | ||
87 | string format = string.Empty; | 95 | string format = string.Empty; |
88 | result = m_MapService.GetMapTile(path.Trim('/'), out format); | 96 | result = m_MapService.GetMapTile(path.Trim('/'), out format); |
89 | if (result.Length > 0) | 97 | if (result.Length > 0) |
@@ -100,6 +108,11 @@ namespace OpenSim.Server.Handlers.MapImage | |||
100 | httpResponse.ContentType = "text/plain"; | 108 | httpResponse.ContentType = "text/plain"; |
101 | } | 109 | } |
102 | 110 | ||
111 | lock (ev) | ||
112 | { | ||
113 | ev.Set(); | ||
114 | } | ||
115 | |||
103 | return result; | 116 | return result; |
104 | } | 117 | } |
105 | 118 | ||