private void HandleImageNotInDatabase(Message m, ViewerConnection vc, ViewerAgentAccessor agent) { ImageNotInDatabase res = (ImageNotInDatabase)m; m_ActiveImageTransfers.Remove(res.ID); vc.PostEvent(new TextureReceivedEvent { Agent = agent, TextureID = res.ID, Success = 0, Data = new ByteArrayApi.ByteArray() }); }
private void TextureDownloadThread(object param) { Thread.CurrentThread.Name = string.Format("LLUDP:Texture Downloader for CircuitCode {0} / IP {1}", CircuitCode, RemoteEndPoint.ToString()); var bakedReqs = new Queue <RequestImage.RequestImageEntry>(); var normalReqs = new Queue <RequestImage.RequestImageEntry>(); var activeRequestImages = new HashSet <UUID>(); #warning Implement Priority handling while (true) { if (!m_TextureDownloadThreadRunning) { return; } try { var req = (bakedReqs.Count != 0 || normalReqs.Count != 0) ? (RequestImage)m_TextureDownloadQueue.Dequeue(0) : (RequestImage)m_TextureDownloadQueue.Dequeue(1000); foreach (var imageRequest in req.RequestImageList) { if (imageRequest.DiscardLevel < 0) { /* skip discard level < 0 */ continue; } if (!activeRequestImages.Contains(imageRequest.ImageID)) { activeRequestImages.Add(imageRequest.ImageID); if (imageRequest.Type == RequestImage.ImageType.Baked || imageRequest.Type == RequestImage.ImageType.ServerBaked) { bakedReqs.Enqueue(imageRequest); } else { normalReqs.Enqueue(imageRequest); } } } } catch { if (bakedReqs.Count == 0 && normalReqs.Count == 0) { continue; } } if (bakedReqs.Count != 0 || normalReqs.Count != 0) { RequestImage.RequestImageEntry imageRequest; try { imageRequest = bakedReqs.Dequeue(); } catch { try { imageRequest = normalReqs.Dequeue(); } catch { continue; } } if (LogUDPTextureDownloads) { m_Log.InfoFormat("Processing texture {0}", imageRequest.ImageID); } /* let us prefer the scene's asset service */ AssetData asset; try { asset = Scene.AssetService[imageRequest.ImageID]; } catch (Exception e1) { try { /* now we try the agent's asset service */ asset = Agent.AssetService[imageRequest.ImageID]; try { /* let us try to store the image locally */ asset.Temporary = true; Scene.AssetService.Store(asset); } catch (Exception e3) { m_Log.DebugFormat("Failed to store asset {0} locally (RequestImage): {1}", imageRequest.ImageID, e3.Message); } } catch (Exception e2) { if (Server.LogAssetFailures) { m_Log.DebugFormat("Failed to download image {0} (RequestImage): {1} or {2}\nA: {3}\nB: {4}", imageRequest.ImageID, e1.Message, e2.Message, e1.StackTrace, e2.StackTrace); } var failres = new ImageNotInDatabase { ID = imageRequest.ImageID }; SendMessage(failres); if (LogUDPTextureDownloads) { m_Log.InfoFormat("texture {0} not found", imageRequest.ImageID); } activeRequestImages.Remove(imageRequest.ImageID); continue; } } ImageCodec codec; switch (asset.Type) { case AssetType.ImageJPEG: codec = ImageCodec.JPEG; break; case AssetType.ImageTGA: case AssetType.TextureTGA: codec = ImageCodec.TGA; break; case AssetType.Texture: codec = ImageCodec.J2C; break; default: var failres = new ImageNotInDatabase { ID = imageRequest.ImageID }; SendMessage(failres); activeRequestImages.Remove(imageRequest.ImageID); if (LogUDPTextureDownloads) { m_Log.InfoFormat("Asset {0} is not a texture", imageRequest.ImageID); } continue; } var res = new ImageData { Codec = codec, ID = imageRequest.ImageID, Size = (uint)asset.Data.Length }; if (asset.Data.Length > IMAGE_FIRST_PACKET_SIZE) { List <Message> messages = new List <Message>(); res.Data = new byte[IMAGE_FIRST_PACKET_SIZE]; Buffer.BlockCopy(asset.Data, 0, res.Data, 0, IMAGE_FIRST_PACKET_SIZE); messages.Add(res); int offset = IMAGE_FIRST_PACKET_SIZE; ushort packetno = 1; while (offset < asset.Data.Length) { var ip = new ImagePacket { ID = imageRequest.ImageID, Packet = packetno++, Data = (asset.Data.Length - offset > IMAGE_PACKET_SIZE) ? new byte[IMAGE_PACKET_SIZE] : new byte[asset.Data.Length - offset] }; Buffer.BlockCopy(asset.Data, offset, ip.Data, 0, ip.Data.Length); messages.Add(ip); offset += IMAGE_PACKET_SIZE; } res.Packets = packetno; foreach (Message m in messages) { SendMessage(m); } } else { res.Data = asset.Data; res.Packets = 1; SendMessage(res); } activeRequestImages.Remove(imageRequest.ImageID); if (LogUDPTextureDownloads) { m_Log.InfoFormat("Download of texture {0} finished", imageRequest.ImageID); } } } }