/// <summary> /// Sends the mapitem response to the IClientAPI /// </summary> /// <param name="response">The OSDMap Response for the mapitem</param> private void RequestMapItemsCompleted(IAsyncResult iar) { AsyncResult result = (AsyncResult)iar; RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate; OSDMap response = (OSDMap)icon.EndInvoke(iar); Interlocked.Decrement(ref nAsyncRequests); if (!response.ContainsKey("requestID")) { return; } UUID requestID = response["requestID"].AsUUID(); if (requestID != UUID.Zero) { MapRequestState mrs = new MapRequestState(); mrs.agentID = UUID.Zero; lock (m_openRequests) { if (m_openRequests.ContainsKey(requestID)) { mrs = m_openRequests[requestID]; m_openRequests.Remove(requestID); } } if (mrs.agentID != UUID.Zero) { ScenePresence av = null; m_scene.TryGetScenePresence(mrs.agentID, out av); if (av != null) { if (response.ContainsKey(mrs.itemtype.ToString())) { List <mapItemReply> returnitems = new List <mapItemReply>(); OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()]; for (int i = 0; i < itemarray.Count; i++) { OSDMap mapitem = (OSDMap)itemarray[i]; mapItemReply mi = new mapItemReply(); mi.x = (uint)mapitem["X"].AsInteger(); mi.y = (uint)mapitem["Y"].AsInteger(); mi.id = mapitem["ID"].AsUUID(); mi.Extra = mapitem["Extra"].AsInteger(); mi.Extra2 = mapitem["Extra2"].AsInteger(); mi.name = mapitem["Name"].AsString(); returnitems.Add(mi); } av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); } } } } }
/// <summary> /// Processing thread main() loop for doing remote mapitem requests /// </summary> public void process() { const int MAX_ASYNC_REQUESTS = 20; try { while (true) { MapRequestState st = requests.Dequeue(1000); // end gracefully if (st.agentID == STOP_UUID) { break; } if (st.agentID != UUID.Zero) { bool dorequest = true; lock (m_rootAgents) { if (!m_rootAgents.Contains(st.agentID)) { dorequest = false; } } if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) { while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break { Thread.Sleep(80); } RequestMapItemsDelegate d = RequestMapItemsAsync; d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null); //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); //RequestMapItemsCompleted(response); Interlocked.Increment(ref nAsyncRequests); } } Watchdog.UpdateThread(); } } catch (Exception e) { m_log.ErrorFormat("[WORLD MAP]: Map item request thread terminated abnormally with exception {0}", e); } threadrunning = false; Watchdog.RemoveThread(); }
/// <summary> /// Enqueue the MapItem request for remote processing /// </summary> /// <param name="httpserver">blank string, we discover this in the process</param> /// <param name="id">Agent ID that we are making this request on behalf</param> /// <param name="flags">passed in from packet</param> /// <param name="EstateID">passed in from packet</param> /// <param name="godlike">passed in from packet</param> /// <param name="itemtype">passed in from packet</param> /// <param name="regionhandle">Region we're looking up</param> public void RequestMapItems(string httpserver, UUID id, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { MapRequestState st = new MapRequestState(); st.agentID = id; st.flags = flags; st.EstateID = EstateID; st.godlike = godlike; st.itemtype = itemtype; st.regionhandle = regionhandle; EnqueueMapItemRequest(st); }
/// <summary> /// Enqueues a 'stop thread' MapRequestState. Causes the MapItemRequest thread to end /// </summary> private void StopThread() { MapRequestState st = new MapRequestState(); st.agentID = STOP_UUID; st.EstateID = 0; st.flags = 0; st.godlike = false; st.itemtype = 0; st.regionhandle = 0; requests.Enqueue(st); }
/// <summary> /// Sends the mapitem response to the IClientAPI /// </summary> /// <param name="response">The OSDMap Response for the mapitem</param> private void RequestMapItemsCompleted(OSDMap response) { UUID requestID = response["requestID"].AsUUID(); if (requestID != UUID.Zero) { MapRequestState mrs = new MapRequestState(); mrs.agentID = UUID.Zero; lock (m_openRequests) { if (m_openRequests.ContainsKey(requestID)) { mrs = m_openRequests[requestID]; m_openRequests.Remove(requestID); } } if (mrs.agentID != UUID.Zero) { ScenePresence av = null; m_scene.TryGetAvatar(mrs.agentID, out av); if (av != null) { if (response.ContainsKey(mrs.itemtype.ToString())) { List <mapItemReply> returnitems = new List <mapItemReply>(); OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()]; for (int i = 0; i < itemarray.Count; i++) { OSDMap mapitem = (OSDMap)itemarray[i]; mapItemReply mi = new mapItemReply(); mi.x = (uint)mapitem["X"].AsInteger(); mi.y = (uint)mapitem["Y"].AsInteger(); mi.id = mapitem["ID"].AsUUID(); mi.Extra = mapitem["Extra"].AsInteger(); mi.Extra2 = mapitem["Extra2"].AsInteger(); mi.name = mapitem["Name"].AsString(); returnitems.Add(mi); } av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); } } } } }
/// <summary> /// Processing thread main() loop for doing remote mapitem requests /// </summary> public void process() { try { while (true) { MapRequestState st = requests.Dequeue(1000); // end gracefully if (st.agentID == STOP_UUID) { break; } if (st.agentID != UUID.Zero) { bool dorequest = true; lock (m_rootAgents) { if (!m_rootAgents.Contains(st.agentID)) { dorequest = false; } } if (dorequest) { OSDMap response = RequestMapItemsAsync("", st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); RequestMapItemsCompleted(response); } } Watchdog.UpdateThread(); } } catch (Exception e) { m_log.ErrorFormat("[WORLD MAP]: Map item request thread terminated abnormally with exception {0}", e); } threadrunning = false; Watchdog.RemoveThread(); }
/// <summary> /// Sends the mapitem response to the IClientAPI /// </summary> /// <param name="response">The OSDMap Response for the mapitem</param> private void RequestMapItemsCompleted(OSDMap response) { UUID requestID = response["requestID"].AsUUID(); if (requestID != UUID.Zero) { MapRequestState mrs = new MapRequestState(); mrs.agentID = UUID.Zero; lock (m_openRequests) { if (m_openRequests.ContainsKey(requestID)) { mrs = m_openRequests[requestID]; m_openRequests.Remove(requestID); } } if (mrs.agentID != UUID.Zero) { ScenePresence av = null; m_scene.TryGetScenePresence(mrs.agentID, out av); if (av != null) { if (response.ContainsKey(mrs.itemtype.ToString())) { List<mapItemReply> returnitems = new List<mapItemReply>(); OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()]; for (int i = 0; i < itemarray.Count; i++) { OSDMap mapitem = (OSDMap)itemarray[i]; mapItemReply mi = new mapItemReply(); mi.x = (uint)mapitem["X"].AsInteger(); mi.y = (uint)mapitem["Y"].AsInteger(); mi.id = mapitem["ID"].AsUUID(); mi.Extra = mapitem["Extra"].AsInteger(); mi.Extra2 = mapitem["Extra2"].AsInteger(); mi.name = mapitem["Name"].AsString(); returnitems.Add(mi); } av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); } } } } }
/// <summary> /// Enqueues the map item request into the processing thread /// </summary> /// <param name="state"></param> public void EnqueueMapItemRequest(MapRequestState state) { requests.Enqueue(state); }
/// <summary> /// Enqueues a 'stop thread' MapRequestState. Causes the MapItemRequest thread to end /// </summary> private void StopThread() { MapRequestState st = new MapRequestState(); st.agentID=STOP_UUID; st.EstateID=0; st.flags=0; st.godlike=false; st.itemtype=0; st.regionhandle=0; requests.Enqueue(st); }
/// <summary> /// Sends the mapitem response to the IClientAPI /// </summary> /// <param name="response">The OSDMap Response for the mapitem</param> private void RequestMapItemsCompleted(IAsyncResult iar) { AsyncResult result = (AsyncResult)iar; RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate; OSDMap response = (OSDMap)icon.EndInvoke(iar); Interlocked.Decrement(ref nAsyncRequests); if (!response.ContainsKey("requestID")) return; UUID requestID = response["requestID"].AsUUID(); if (requestID != UUID.Zero) { MapRequestState mrs = new MapRequestState(); mrs.agentID = UUID.Zero; lock (m_openRequests) { if (m_openRequests.ContainsKey(requestID)) { mrs = m_openRequests[requestID]; m_openRequests.Remove(requestID); } } if (mrs.agentID != UUID.Zero) { ScenePresence av = null; m_scene.TryGetScenePresence(mrs.agentID, out av); if (av != null) { if (response.ContainsKey(mrs.itemtype.ToString())) { List<mapItemReply> returnitems = new List<mapItemReply>(); OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()]; for (int i = 0; i < itemarray.Count; i++) { OSDMap mapitem = (OSDMap)itemarray[i]; mapItemReply mi = new mapItemReply(); mi.x = (uint)mapitem["X"].AsInteger(); mi.y = (uint)mapitem["Y"].AsInteger(); mi.id = mapitem["ID"].AsUUID(); mi.Extra = mapitem["Extra"].AsInteger(); mi.Extra2 = mapitem["Extra2"].AsInteger(); mi.name = mapitem["Name"].AsString(); returnitems.Add(mi); } av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); } // Service 7 (MAP_ITEM_LAND_FOR_SALE) uint itemtype = 7; if (response.ContainsKey(itemtype.ToString())) { List<mapItemReply> returnitems = new List<mapItemReply>(); OSDArray itemarray = (OSDArray)response[itemtype.ToString()]; for (int i = 0; i < itemarray.Count; i++) { OSDMap mapitem = (OSDMap)itemarray[i]; mapItemReply mi = new mapItemReply(); mi.x = (uint)mapitem["X"].AsInteger(); mi.y = (uint)mapitem["Y"].AsInteger(); mi.id = mapitem["ID"].AsUUID(); mi.Extra = mapitem["Extra"].AsInteger(); mi.Extra2 = mapitem["Extra2"].AsInteger(); mi.name = mapitem["Name"].AsString(); returnitems.Add(mi); } av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); } // Service 1 (MAP_ITEM_TELEHUB) itemtype = 1; if (response.ContainsKey(itemtype.ToString())) { List<mapItemReply> returnitems = new List<mapItemReply>(); OSDArray itemarray = (OSDArray)response[itemtype.ToString()]; for (int i = 0; i < itemarray.Count; i++) { OSDMap mapitem = (OSDMap)itemarray[i]; mapItemReply mi = new mapItemReply(); mi.x = (uint)mapitem["X"].AsInteger(); mi.y = (uint)mapitem["Y"].AsInteger(); mi.id = mapitem["ID"].AsUUID(); mi.Extra = mapitem["Extra"].AsInteger(); mi.Extra2 = mapitem["Extra2"].AsInteger(); mi.name = mapitem["Name"].AsString(); returnitems.Add(mi); } av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); } } } } }
/// <summary> /// Does the actual remote mapitem request /// This should be called from an asynchronous thread /// Request failures get blacklisted until region restart so we don't /// continue to spend resources trying to contact regions that are down. /// </summary> /// <param name="httpserver">blank string, we discover this in the process</param> /// <param name="id">Agent ID that we are making this request on behalf</param> /// <param name="flags">passed in from packet</param> /// <param name="EstateID">passed in from packet</param> /// <param name="godlike">passed in from packet</param> /// <param name="itemtype">passed in from packet</param> /// <param name="regionhandle">Region we're looking up</param> /// <returns></returns> private OSDMap RequestMapItemsAsync(UUID id, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { // m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); string httpserver = ""; bool blacklisted = false; lock (m_blacklistedregions) { if (m_blacklistedregions.ContainsKey(regionhandle)) { if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout)) { m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted region {0}", regionhandle); m_blacklistedregions.Remove(regionhandle); } else blacklisted = true; } } if (blacklisted) return new OSDMap(); UUID requestID = UUID.Random(); lock (m_cachedRegionMapItemsAddress) { if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) httpserver = m_cachedRegionMapItemsAddress[regionhandle]; } if (httpserver.Length == 0) { uint x = 0, y = 0; Util.RegionHandleToWorldLoc(regionhandle, out x, out y); GridRegion mreg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); if (mreg != null) { httpserver = mreg.ServerURI + "MAP/MapItems/" + regionhandle.ToString(); lock (m_cachedRegionMapItemsAddress) { if (!m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) m_cachedRegionMapItemsAddress.Add(regionhandle, httpserver); } } else { lock (m_blacklistedregions) { if (!m_blacklistedregions.ContainsKey(regionhandle)) m_blacklistedregions.Add(regionhandle, Environment.TickCount); } //m_log.InfoFormat("[WORLD MAP]: Blacklisted region {0}", regionhandle.ToString()); } } blacklisted = false; lock (m_blacklistedurls) { if (m_blacklistedurls.ContainsKey(httpserver)) { if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout)) { m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted URL {0}", httpserver); m_blacklistedurls.Remove(httpserver); } else blacklisted = true; } } // Can't find the http server if (httpserver.Length == 0 || blacklisted) return new OSDMap(); MapRequestState mrs = new MapRequestState(); mrs.agentID = id; mrs.EstateID = EstateID; mrs.flags = flags; mrs.godlike = godlike; mrs.itemtype=itemtype; mrs.regionhandle = regionhandle; lock (m_openRequests) m_openRequests.Add(requestID, mrs); WebRequest mapitemsrequest = null; try { mapitemsrequest = WebRequest.Create(httpserver); } catch (Exception e) { m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); return new OSDMap(); } mapitemsrequest.Method = "POST"; mapitemsrequest.ContentType = "application/xml+llsd"; OSDMap RAMap = new OSDMap(); // string RAMapString = RAMap.ToString(); OSD LLSDofRAMap = RAMap; // RENAME if this works byte[] buffer = OSDParser.SerializeLLSDXmlBytes(LLSDofRAMap); OSDMap responseMap = new OSDMap(); responseMap["requestID"] = OSD.FromUUID(requestID); Stream os = null; try { // send the Post mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send os = mapitemsrequest.GetRequestStream(); os.Write(buffer, 0, buffer.Length); //Send it //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver); } catch (WebException ex) { m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedurls) { if (!m_blacklistedurls.ContainsKey(httpserver)) m_blacklistedurls.Add(httpserver, Environment.TickCount); } m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); return responseMap; } catch { m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); responseMap["connect"] = OSD.FromBoolean(false); return responseMap; } finally { if (os != null) os.Dispose(); } string response_mapItems_reply = null; { try { using (WebResponse webResponse = mapitemsrequest.GetResponse()) { if (webResponse != null) { using (Stream s = webResponse.GetResponseStream()) using (StreamReader sr = new StreamReader(s)) response_mapItems_reply = sr.ReadToEnd().Trim(); } else { return new OSDMap(); } } } catch (WebException) { responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedurls) { if (!m_blacklistedurls.ContainsKey(httpserver)) m_blacklistedurls.Add(httpserver, Environment.TickCount); } m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); return responseMap; } catch { m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedregions) { if (!m_blacklistedregions.ContainsKey(regionhandle)) m_blacklistedregions.Add(regionhandle, Environment.TickCount); } return responseMap; } OSD rezResponse = null; try { rezResponse = OSDParser.DeserializeLLSDXml(response_mapItems_reply); responseMap = (OSDMap)rezResponse; responseMap["requestID"] = OSD.FromUUID(requestID); } catch (Exception ex) { m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedregions) { if (!m_blacklistedregions.ContainsKey(regionhandle)) m_blacklistedregions.Add(regionhandle, Environment.TickCount); } return responseMap; } } if (!responseMap.ContainsKey(itemtype.ToString())) // remote sim doesnt have the stated region handle { m_log.DebugFormat("[WORLD MAP]: Remote sim does not have the stated region. Blacklisting."); lock (m_blacklistedregions) { if (!m_blacklistedregions.ContainsKey(regionhandle)) m_blacklistedregions.Add(regionhandle, Environment.TickCount); } } return responseMap; }
/// <summary> /// Enqueues the map item request into the services throttle processing thread /// </summary> /// <param name="state"></param> public void EnqueueMapItemRequest(MapRequestState st) { m_ServiceThrottle.Enqueue("map-item", st.regionhandle.ToString() + st.agentID.ToString(), delegate { if (st.agentID != UUID.Zero) { bool dorequest = true; lock (m_rootAgents) { if (!m_rootAgents.Contains(st.agentID)) dorequest = false; } if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) { if (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break { // AH!!! Recursive ! // Put this request back in the queue and return EnqueueMapItemRequest(st); return; } RequestMapItemsDelegate d = RequestMapItemsAsync; d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null); //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); //RequestMapItemsCompleted(response); Interlocked.Increment(ref nAsyncRequests); } } }); }
/// <summary> /// Does the actual remote mapitem request /// This should be called from an asynchronous thread /// Request failures get blacklisted until region restart so we don't /// continue to spend resources trying to contact regions that are down. /// </summary> /// <param name="httpserver">blank string, we discover this in the process</param> /// <param name="id">Agent ID that we are making this request on behalf</param> /// <param name="flags">passed in from packet</param> /// <param name="EstateID">passed in from packet</param> /// <param name="godlike">passed in from packet</param> /// <param name="itemtype">passed in from packet</param> /// <param name="regionhandle">Region we're looking up</param> /// <returns></returns> private OSDMap RequestMapItemsAsync(string httpserver, UUID id, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { bool blacklisted = false; lock (m_blacklistedregions) { if (m_blacklistedregions.ContainsKey(regionhandle)) { blacklisted = true; } } if (blacklisted) { return(new OSDMap()); } UUID requestID = UUID.Random(); lock (m_cachedRegionMapItemsAddress) { if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) { httpserver = m_cachedRegionMapItemsAddress[regionhandle]; } } if (httpserver.Length == 0) { uint x = 0, y = 0; Utils.LongToUInts(regionhandle, out x, out y); GridRegion mreg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); if (mreg != null) { httpserver = "http://" + mreg.ExternalEndPoint.Address.ToString() + ":" + mreg.HttpPort + "/MAP/MapItems/" + regionhandle.ToString(); lock (m_cachedRegionMapItemsAddress) { if (!m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) { m_cachedRegionMapItemsAddress.Add(regionhandle, httpserver); } } } else { lock (m_blacklistedregions) { if (!m_blacklistedregions.ContainsKey(regionhandle)) { m_blacklistedregions.Add(regionhandle, Environment.TickCount); } } m_log.InfoFormat("[WORLD MAP]: Blacklisted region {0}", regionhandle.ToString()); } } blacklisted = false; lock (m_blacklistedurls) { if (m_blacklistedurls.ContainsKey(httpserver)) { blacklisted = true; } } // Can't find the http server if (httpserver.Length == 0 || blacklisted) { return(new OSDMap()); } MapRequestState mrs = new MapRequestState(); mrs.agentID = id; mrs.EstateID = EstateID; mrs.flags = flags; mrs.godlike = godlike; mrs.itemtype = itemtype; mrs.regionhandle = regionhandle; lock (m_openRequests) m_openRequests.Add(requestID, mrs); WebRequest mapitemsrequest = WebRequest.Create(httpserver); mapitemsrequest.Method = "POST"; mapitemsrequest.ContentType = "application/xml+llsd"; OSDMap RAMap = new OSDMap(); // string RAMapString = RAMap.ToString(); OSD LLSDofRAMap = RAMap; // RENAME if this works byte[] buffer = OSDParser.SerializeLLSDXmlBytes(LLSDofRAMap); OSDMap responseMap = new OSDMap(); responseMap["requestID"] = OSD.FromUUID(requestID); Stream os = null; try { // send the Post mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send os = mapitemsrequest.GetRequestStream(); os.Write(buffer, 0, buffer.Length); //Send it os.Close(); //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from Sim {0}", httpserver); } catch (WebException ex) { m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedurls) { if (!m_blacklistedurls.ContainsKey(httpserver)) { m_blacklistedurls.Add(httpserver, Environment.TickCount); } } m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); return(responseMap); } string response_mapItems_reply = null; { // get the response try { WebResponse webResponse = mapitemsrequest.GetResponse(); if (webResponse != null) { StreamReader sr = new StreamReader(webResponse.GetResponseStream()); response_mapItems_reply = sr.ReadToEnd().Trim(); } else { return(new OSDMap()); } } catch (WebException) { responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedurls) { if (!m_blacklistedurls.ContainsKey(httpserver)) { m_blacklistedurls.Add(httpserver, Environment.TickCount); } } m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); return(responseMap); } OSD rezResponse = null; try { rezResponse = OSDParser.DeserializeLLSDXml(response_mapItems_reply); responseMap = (OSDMap)rezResponse; responseMap["requestID"] = OSD.FromUUID(requestID); } catch (Exception) { //m_log.InfoFormat("[OGP]: exception on parse of rez reply {0}", ex.Message); responseMap["connect"] = OSD.FromBoolean(false); return(responseMap); } } return(responseMap); }
/// <summary> /// Does the actual remote mapitem request /// This should be called from an asynchronous thread /// Request failures get blacklisted until region restart so we don't /// continue to spend resources trying to contact regions that are down. /// </summary> /// <param name="httpserver">blank string, we discover this in the process</param> /// <param name="id">Agent ID that we are making this request on behalf</param> /// <param name="flags">passed in from packet</param> /// <param name="EstateID">passed in from packet</param> /// <param name="godlike">passed in from packet</param> /// <param name="itemtype">passed in from packet</param> /// <param name="regionhandle">Region we're looking up</param> /// <returns></returns> private OSDMap RequestMapItemsAsync(string httpserver, UUID id, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { bool blacklisted = false; lock (m_blacklistedregions) { if (m_blacklistedregions.ContainsKey(regionhandle)) blacklisted = true; } if (blacklisted) return new OSDMap(); UUID requestID = UUID.Random(); lock (m_cachedRegionMapItemsAddress) { if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) httpserver = m_cachedRegionMapItemsAddress[regionhandle]; } if (httpserver.Length == 0) { uint x = 0, y = 0; Utils.LongToUInts(regionhandle, out x, out y); GridRegion mreg = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); if (mreg != null) { httpserver = "http://" + mreg.ExternalEndPoint.Address.ToString() + ":" + mreg.HttpPort + "/MAP/MapItems/" + regionhandle.ToString(); lock (m_cachedRegionMapItemsAddress) { if (!m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) m_cachedRegionMapItemsAddress.Add(regionhandle, httpserver); } } else { lock (m_blacklistedregions) { if (!m_blacklistedregions.ContainsKey(regionhandle)) m_blacklistedregions.Add(regionhandle, Environment.TickCount); } m_log.InfoFormat("[WORLD MAP]: Blacklisted region {0}", regionhandle.ToString()); } } blacklisted = false; lock (m_blacklistedurls) { if (m_blacklistedurls.ContainsKey(httpserver)) blacklisted = true; } // Can't find the http server if (httpserver.Length == 0 || blacklisted) return new OSDMap(); MapRequestState mrs = new MapRequestState(); mrs.agentID = id; mrs.EstateID = EstateID; mrs.flags = flags; mrs.godlike = godlike; mrs.itemtype=itemtype; mrs.regionhandle = regionhandle; lock (m_openRequests) m_openRequests.Add(requestID, mrs); WebRequest mapitemsrequest = WebRequest.Create(httpserver); mapitemsrequest.Method = "POST"; mapitemsrequest.ContentType = "application/xml+llsd"; OSDMap RAMap = new OSDMap(); // string RAMapString = RAMap.ToString(); OSD LLSDofRAMap = RAMap; // RENAME if this works byte[] buffer = OSDParser.SerializeLLSDXmlBytes(LLSDofRAMap); OSDMap responseMap = new OSDMap(); responseMap["requestID"] = OSD.FromUUID(requestID); Stream os = null; try { // send the Post mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send os = mapitemsrequest.GetRequestStream(); os.Write(buffer, 0, buffer.Length); //Send it os.Close(); //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from Sim {0}", httpserver); } catch (WebException ex) { m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedurls) { if (!m_blacklistedurls.ContainsKey(httpserver)) m_blacklistedurls.Add(httpserver, Environment.TickCount); } m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); return responseMap; } string response_mapItems_reply = null; { // get the response try { WebResponse webResponse = mapitemsrequest.GetResponse(); if (webResponse != null) { StreamReader sr = new StreamReader(webResponse.GetResponseStream()); response_mapItems_reply = sr.ReadToEnd().Trim(); } else { return new OSDMap(); } } catch (WebException) { responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedurls) { if (!m_blacklistedurls.ContainsKey(httpserver)) m_blacklistedurls.Add(httpserver, Environment.TickCount); } m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); return responseMap; } OSD rezResponse = null; try { rezResponse = OSDParser.DeserializeLLSDXml(response_mapItems_reply); responseMap = (OSDMap)rezResponse; responseMap["requestID"] = OSD.FromUUID(requestID); } catch (Exception) { //m_log.InfoFormat("[OGP]: exception on parse of rez reply {0}", ex.Message); responseMap["connect"] = OSD.FromBoolean(false); return responseMap; } } return responseMap; }