From 611327e1040fa706665c543f67f9331a7e0136c5 Mon Sep 17 00:00:00 2001 From: MW Date: Mon, 10 Dec 2007 13:27:23 +0000 Subject: more work on texture downloading. Refractored the TextureDownloadModule (but currently to make debugging easier, it is running as a non shared module, so this results in a instance of this module being created for each region (and a extra thread per region), this will be changed back soon. Removed the old texture handling/sending code from AssetCache. A few other small changes/fixes. --- .../Framework/Communications/Cache/AssetCache.cs | 303 +++------------------ .../Cache/AssetTransactionManager.cs | 4 +- .../Communications/Cache/AssetTransactions.cs | 127 ++++----- .../Framework/Communications/Capabilities/LLSD.cs | 2 +- 4 files changed, 107 insertions(+), 329 deletions(-) (limited to 'OpenSim/Framework/Communications') diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs index d5ac67b..c164f0c 100644 --- a/OpenSim/Framework/Communications/Cache/AssetCache.cs +++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs @@ -36,8 +36,7 @@ using OpenSim.Framework.Console; namespace OpenSim.Framework.Communications.Cache { - public delegate void DownloadComplete(AssetCache.TextureSender sender); - + public delegate void AssetRequestCallback(LLUUID assetID, AssetBase asset); /// @@ -57,21 +56,11 @@ namespace OpenSim.Framework.Communications.Cache public Dictionary RequestedTextures = new Dictionary(); //Textures requested from the asset server - public Dictionary SendingTextures = new Dictionary(); - public Dictionary RequestLists = new Dictionary(); - private BlockingQueue m_queueTextures = new BlockingQueue(); - private Dictionary> m_avatarReceivedTextures = new Dictionary>(); - - private Dictionary> m_timesTextureSent = - new Dictionary>(); - - private IAssetServer m_assetServer; private Thread m_assetCacheThread; - private Thread m_textureSenderThread; private LogBase m_log; /// @@ -88,9 +77,7 @@ namespace OpenSim.Framework.Communications.Cache m_assetCacheThread.IsBackground = true; m_assetCacheThread.Start(); - m_textureSenderThread = new Thread(new ThreadStart(ProcessTextureSenders)); - m_textureSenderThread.IsBackground = true; - m_textureSenderThread.Start(); + m_log = log; } @@ -104,7 +91,6 @@ namespace OpenSim.Framework.Communications.Cache try { ProcessAssetQueue(); - ProcessTextureQueue(); Thread.Sleep(500); } catch (Exception e) @@ -188,7 +174,7 @@ namespace OpenSim.Framework.Communications.Cache if (asset.Type == 0) { - if(Textures.ContainsKey(asset.FullID)) + if (Textures.ContainsKey(asset.FullID)) { result = "Duplicate ignored."; } @@ -250,67 +236,7 @@ namespace OpenSim.Framework.Communications.Cache return asset; } - /// - /// - /// - private void ProcessTextureQueue() - { - if (TextureRequests.Count == 0) - { - //no requests waiting - return; - } - int num; - num = TextureRequests.Count; - AssetRequest req; - for (int i = 0; i < num; i++) - { - req = (AssetRequest) TextureRequests[i]; - if (!SendingTextures.ContainsKey(req.ImageInfo.FullID)) - { - //Console.WriteLine("new texture to send"); - TextureSender sender = new TextureSender(req); - //sender.OnComplete += this.TextureSent; - SendingTextures.Add(req.ImageInfo.FullID, sender); - m_queueTextures.Enqueue(sender); - } - } - - TextureRequests.Clear(); - } - - public void ProcessTextureSenders() - { - while (true) - { - TextureSender sender = m_queueTextures.Dequeue(); - - bool finished = sender.SendTexture(); - if (finished) - { - TextureSent(sender); - } - else - { - // Console.WriteLine("readding texture"); - m_queueTextures.Enqueue(sender); - } - } - } - - /// - /// Event handler, called by a TextureSender object to say that texture has been sent - /// - /// - public void TextureSent(TextureSender sender) - { - if (SendingTextures.ContainsKey(sender.request.ImageInfo.FullID)) - { - SendingTextures.Remove(sender.request.ImageInfo.FullID); - // this.m_avatarReceivedTextures[sender.request.RequestUser.AgentId].Add(sender.request.ImageInfo.FullID); - } - } public void AssetReceived(AssetBase asset, bool IsTexture) { @@ -354,7 +280,7 @@ namespace OpenSim.Framework.Communications.Cache if (assetInf.Data.LongLength > 600) { //over 600 bytes so split up file - req.NumPackets = 1 + (int) (assetInf.Data.Length - 600 + 999)/1000; + req.NumPackets = 1 + (int)(assetInf.Data.Length - 600 + 999) / 1000; } else { @@ -400,6 +326,20 @@ namespace OpenSim.Framework.Communications.Cache //} } + private int CalculateNumPackets(int length) + { + int numPackets = 1; + + if (length > 600) + { + //over 600 bytes so split up file + int restData = (length - 600); + int restPackets = ((restData + 999) / 1000); + numPackets = 1 + restPackets; + } + + return numPackets; + } #region Assets /// @@ -458,7 +398,7 @@ namespace OpenSim.Framework.Communications.Cache if (asset.Data.LongLength > 600) { //over 600 bytes so split up file - req.NumPackets = 1 + (int) (asset.Data.Length - 600 + 999)/1000; + req.NumPackets = 1 + (int)(asset.Data.Length - 600 + 999) / 1000; } else { @@ -473,6 +413,7 @@ namespace OpenSim.Framework.Communications.Cache /// private void ProcessAssetQueue() { + //should move the asset downloading to a module, like has been done with texture downloading if (AssetRequests.Count == 0) { //no requests waiting @@ -492,7 +433,7 @@ namespace OpenSim.Framework.Communications.Cache AssetRequest req; for (int i = 0; i < num; i++) { - req = (AssetRequest) AssetRequests[i]; + req = (AssetRequest)AssetRequests[i]; //Console.WriteLine("sending asset " + req.RequestAssetID); TransferInfoPacket Transfer = new TransferInfoPacket(); Transfer.TransferInfo.ChannelType = 2; @@ -502,7 +443,7 @@ namespace OpenSim.Framework.Communications.Cache { Transfer.TransferInfo.Params = new byte[20]; Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); - int assType = (int) req.AssetInf.Type; + int assType = (int)req.AssetInf.Type; Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); } else if (req.AssetRequestSource == 3) @@ -512,9 +453,9 @@ namespace OpenSim.Framework.Communications.Cache //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); } - Transfer.TransferInfo.Size = (int) req.AssetInf.Data.Length; + Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length; Transfer.TransferInfo.TransferID = req.TransferRequestID; - req.RequestUser.OutPacket(Transfer,ThrottleOutPacketType.Asset); + req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset); if (req.NumPackets == 1) { @@ -573,79 +514,6 @@ namespace OpenSim.Framework.Communications.Cache #endregion - #region Textures - - /// - /// - /// - /// - /// - public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID, uint packetNumber, int discard) - { - // System.Console.WriteLine("texture request for " + imageID.ToStringHyphenated() + " packetnumber= " + packetNumber); - //check to see if texture is in local cache, if not request from asset server - if (!m_avatarReceivedTextures.ContainsKey(userInfo.AgentId)) - { - m_avatarReceivedTextures.Add(userInfo.AgentId, new List()); - } - /* if(this.m_avatarReceivedTextures[userInfo.AgentId].Contains(imageID)) - { - //Console.WriteLine(userInfo.AgentId +" is requesting a image( "+ imageID+" that has already been sent to them"); - return; - }*/ - - if (!Textures.ContainsKey(imageID)) - { - if (!RequestedTextures.ContainsKey(imageID)) - { - //not is cache so request from asset server - AssetRequest request = new AssetRequest(); - request.RequestUser = userInfo; - request.RequestAssetID = imageID; - request.IsTextureRequest = true; - request.DiscardLevel = discard; - RequestedTextures.Add(imageID, request); - m_assetServer.RequestAsset(imageID, true); - } - return; - } - - // System.Console.WriteLine("texture already in cache"); - TextureImage imag = Textures[imageID]; - AssetRequest req = new AssetRequest(); - req.RequestUser = userInfo; - req.RequestAssetID = imageID; - req.IsTextureRequest = true; - req.ImageInfo = imag; - req.DiscardLevel = discard; - - req.NumPackets = CalculateNumPackets(imag.Data.Length); - - if (packetNumber != 0) - { - req.PacketCounter = (int) packetNumber; - } - - TextureRequests.Add(req); - } - - private int CalculateNumPackets(int length) - { - int numPackets = 1; - - if (length > 600) - { - //over 600 bytes so split up file - int restData = (length - 600); - int restPackets = ((restData+999)/1000); - numPackets = 1 + restPackets; - } - - return numPackets; - } - - #endregion - public class AssetRequest { public IClientAPI RequestUser; @@ -702,123 +570,28 @@ namespace OpenSim.Framework.Communications.Cache } } - public class TextureSender - { - public AssetRequest request; - private int counter = 0; - - public TextureSender(AssetRequest req) - { - request = req; - } - - public bool SendTexture() - { - SendPacket(); - counter++; - - if ((request.PacketCounter >= request.NumPackets) || counter > 100 || (request.NumPackets == 1) || - (request.DiscardLevel == -1)) - { - return true; - } - return false; - } - public void SendPacket() - { - AssetRequest req = request; - //Console.WriteLine("sending " + req.ImageInfo.FullID); - if (req.PacketCounter == 0) - { - //first time for this request so send imagedata packet - if (req.NumPackets == 1) - { - //Console.WriteLine("only one packet so send whole file"); - ImageDataPacket im = new ImageDataPacket(); - im.Header.Reliable = false; - im.ImageID.Packets = 1; - im.ImageID.ID = req.ImageInfo.FullID; - im.ImageID.Size = (uint) req.ImageInfo.Data.Length; - im.ImageData.Data = req.ImageInfo.Data; - im.ImageID.Codec = 2; - req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); - req.PacketCounter++; - //req.ImageInfo.l= time; - //System.Console.WriteLine("sent texture: " + req.ImageInfo.FullID); - //Console.WriteLine("sending single packet for " + req.ImageInfo.FullID.ToStringHyphenated()); - } - else - { - //more than one packet so split file up - ImageDataPacket im = new ImageDataPacket(); - im.Header.Reliable = false; - im.ImageID.Packets = (ushort) (req.NumPackets); - im.ImageID.ID = req.ImageInfo.FullID; - im.ImageID.Size = (uint) req.ImageInfo.Data.Length; - im.ImageData.Data = new byte[600]; - Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600); - im.ImageID.Codec = 2; - req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); - - req.PacketCounter++; - //req.ImageInfo.last_used = time; - //System.Console.WriteLine("sent first packet of texture: " + req.ImageInfo.FullID); - //Console.WriteLine("sending packet 1 for " + req.ImageInfo.FullID.ToStringHyphenated()); - } - } - else - { - //Console.WriteLine("sending packet " + req.PacketCounter + " for " + req.ImageInfo.FullID.ToStringHyphenated()); - //send imagepacket - //more than one packet so split file up - ImagePacketPacket im = new ImagePacketPacket(); - im.Header.Reliable = false; - im.ImageID.Packet = (ushort) (req.PacketCounter); - im.ImageID.ID = req.ImageInfo.FullID; - int size = req.ImageInfo.Data.Length - 600 - (1000*(req.PacketCounter - 1)); - if (size > 1000) size = 1000; - //Console.WriteLine("length= {0} counter= {1} size= {2}",req.ImageInfo.Data.Length, req.PacketCounter, size); - im.ImageData.Data = new byte[size]; - Array.Copy(req.ImageInfo.Data, 600 + (1000*(req.PacketCounter - 1)), im.ImageData.Data, 0, size); - req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); - req.PacketCounter++; - //req.ImageInfo.last_used = time; - //System.Console.WriteLine("sent a packet of texture: "+req.ImageInfo.FullID); - } - } + public class AssetRequestsList + { + public LLUUID AssetID; + public List Requests = new List(); - private void SaveAssetToFile(string filename, byte[] data) + public AssetRequestsList(LLUUID assetID) { - FileStream fs = File.Create(filename); - BinaryWriter bw = new BinaryWriter(fs); - bw.Write(data); - bw.Close(); - fs.Close(); + AssetID = assetID; } } - } - - public class AssetRequestsList - { - public LLUUID AssetID; - public List Requests = new List(); - public AssetRequestsList(LLUUID assetID) + public class NewAssetRequest { - AssetID = assetID; - } - } - - public class NewAssetRequest - { - public LLUUID AssetID; - public AssetRequestCallback Callback; + public LLUUID AssetID; + public AssetRequestCallback Callback; - public NewAssetRequest(LLUUID assetID, AssetRequestCallback callback) - { - AssetID = assetID; - Callback = callback; + public NewAssetRequest(LLUUID assetID, AssetRequestCallback callback) + { + AssetID = assetID; + Callback = callback; + } } } } diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs b/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs index 580c56a..7de84fa 100644 --- a/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs +++ b/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs @@ -83,7 +83,7 @@ namespace OpenSim.Framework.Communications.Cache } public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, - byte[] data, bool storeLocal) + byte[] data, bool storeLocal, bool tempFile) { // Console.WriteLine("asset upload of " + assetID); AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId); @@ -92,7 +92,7 @@ namespace OpenSim.Framework.Communications.Cache AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); if (uploader != null) { - uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal); + uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); } } } diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs b/OpenSim/Framework/Communications/Cache/AssetTransactions.cs index f972368..51b80e5 100644 --- a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs +++ b/OpenSim/Framework/Communications/Cache/AssetTransactions.cs @@ -113,66 +113,6 @@ namespace OpenSim.Framework.Communications.Cache } // Nested Types - public class AssetCapsUploader - { - // Fields - private BaseHttpServer httpListener; - private LLUUID inventoryItemID; - private string m_assetDescription = ""; - private string m_assetName = ""; - private LLUUID m_folderID; - private LLUUID newAssetID; - private bool m_dumpImageToFile; - private string uploaderPath = ""; - - // Events - public event UpLoadedAsset OnUpLoad; - - // Methods - public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, - LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile) - { - m_assetName = assetName; - m_assetDescription = assetDescription; - m_folderID = folderID; - newAssetID = assetID; - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - m_dumpImageToFile = dumpImageToFile; - } - - private void SaveImageToFile(string filename, byte[] data) - { - FileStream output = File.Create(filename); - BinaryWriter writer = new BinaryWriter(output); - writer.Write(data); - writer.Close(); - output.Close(); - } - - public string uploaderCaps(byte[] data, string path, string param) - { - LLUUID inventoryItemID = this.inventoryItemID; - string text = ""; - LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); - complete.new_asset = newAssetID.ToStringHyphenated(); - complete.new_inventory_item = inventoryItemID; - complete.state = "complete"; - text = LLSDHelpers.SerialiseLLSDReply(complete); - httpListener.RemoveStreamHandler("POST", uploaderPath); - if (m_dumpImageToFile) - { - SaveImageToFile(m_assetName + ".jp2", data); - } - if (OnUpLoad != null) - { - OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, "", ""); - } - return text; - } - } - public class AssetXferUploader { // Fields @@ -230,7 +170,7 @@ namespace OpenSim.Framework.Communications.Cache } public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, - bool storeLocal) + bool storeLocal, bool tempFile) { ourClient = remoteClient; Asset = new AssetBase(); @@ -240,6 +180,9 @@ namespace OpenSim.Framework.Communications.Cache Asset.Data = data; Asset.Name = "blank"; Asset.Description = "empty"; + Asset.Local = storeLocal; + Asset.Temporary = tempFile; + TransactionID = transaction; m_storeLocal = storeLocal; if (Asset.Data.Length > 2) @@ -368,6 +311,67 @@ namespace OpenSim.Framework.Communications.Cache } } + #region Nested Classes currently not in use (waiting for them to be enabled) + public class AssetCapsUploader + { + // Fields + private BaseHttpServer httpListener; + private LLUUID inventoryItemID; + private string m_assetDescription = ""; + private string m_assetName = ""; + private LLUUID m_folderID; + private LLUUID newAssetID; + private bool m_dumpImageToFile; + private string uploaderPath = ""; + + // Events + public event UpLoadedAsset OnUpLoad; + + // Methods + public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, + LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile) + { + m_assetName = assetName; + m_assetDescription = assetDescription; + m_folderID = folderID; + newAssetID = assetID; + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + m_dumpImageToFile = dumpImageToFile; + } + + private void SaveImageToFile(string filename, byte[] data) + { + FileStream output = File.Create(filename); + BinaryWriter writer = new BinaryWriter(output); + writer.Write(data); + writer.Close(); + output.Close(); + } + + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inventoryItemID = this.inventoryItemID; + string text = ""; + LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); + complete.new_asset = newAssetID.ToStringHyphenated(); + complete.new_inventory_item = inventoryItemID; + complete.state = "complete"; + text = LLSDHelpers.SerialiseLLSDReply(complete); + httpListener.RemoveStreamHandler("POST", uploaderPath); + if (m_dumpImageToFile) + { + SaveImageToFile(m_assetName + ".jp2", data); + } + if (OnUpLoad != null) + { + OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, "", ""); + } + return text; + } + } + public class NoteCardCapsUpdate { // Fields @@ -420,5 +424,6 @@ namespace OpenSim.Framework.Communications.Cache return text; } } + #endregion } } diff --git a/OpenSim/Framework/Communications/Capabilities/LLSD.cs b/OpenSim/Framework/Communications/Capabilities/LLSD.cs index 60b5f75..4efeeb1 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSD.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSD.cs @@ -10,7 +10,7 @@ using System.Text; namespace OpenSim.Region.Capabilities { /// - /// + /// Borrowed from (a older version of ) libsl for now, as their new llsd code doesn't work we our decoding code. /// public static class LLSD { -- cgit v1.1