/// <summary> /// /// </summary> /// <param name="upload"></param> void Assets_OnUploadProgress(AssetUpload upload) { if (upload.Transferred == upload.Size) { WaitForUploadComplete.Set(); } else { //Console.WriteLine("Progress: {0}/{1} {2}/{3} {4}", upload.XferID, upload.ID, upload.Transferred, upload.Size, upload.Success); Console.Write("."); } }
/// <summary> /// Initiate an asset upload /// </summary> /// <param name="assetID">The ID this asset will have if the /// upload succeeds</param> /// <param name="type">Asset type to upload this data as</param> /// <param name="data">Raw asset data to upload</param> /// <param name="storeLocal">Whether to store this asset on the local /// simulator or the grid-wide asset server</param> /// <param name="transactionID">The tranaction id for the upload <see cref="RequestCreateItem"/></param> /// <returns>The transaction ID of this transfer</returns> public UUID RequestUpload(out UUID assetID, AssetType type, byte[] data, bool storeLocal, UUID transactionID) { AssetUpload upload = new AssetUpload(); upload.AssetData = data; upload.AssetType = type; assetID = UUID.Combine(transactionID, Client.Self.SecureSessionID); upload.AssetID = assetID; upload.Size = data.Length; upload.XferID = 0; upload.ID = transactionID; // Build and send the upload packet AssetUploadRequestPacket request = new AssetUploadRequestPacket(); request.AssetBlock.StoreLocal = storeLocal; request.AssetBlock.Tempfile = false; // This field is deprecated request.AssetBlock.TransactionID = transactionID; request.AssetBlock.Type = (sbyte)type; bool isMultiPacketUpload; if (data.Length + 100 < Settings.MAX_PACKET_SIZE) { isMultiPacketUpload = false; Logger.Log( String.Format("Beginning asset upload [Single Packet], ID: {0}, AssetID: {1}, Size: {2}", upload.ID.ToString(), upload.AssetID.ToString(), upload.Size), Helpers.LogLevel.Info, Client); Transfers[upload.ID] = upload; // The whole asset will fit in this packet, makes things easy request.AssetBlock.AssetData = data; upload.Transferred = data.Length; } else { isMultiPacketUpload = true; Logger.Log( String.Format("Beginning asset upload [Multiple Packets], ID: {0}, AssetID: {1}, Size: {2}", upload.ID.ToString(), upload.AssetID.ToString(), upload.Size), Helpers.LogLevel.Info, Client); // Asset is too big, send in multiple packets request.AssetBlock.AssetData = Utils.EmptyBytes; } // Wait for the previous upload to receive a RequestXferPacket lock (PendingUploadLock) { const int UPLOAD_CONFIRM_TIMEOUT = 20 * 1000; const int SLEEP_INTERVAL = 50; int t = 0; while (WaitingForUploadConfirm && t < UPLOAD_CONFIRM_TIMEOUT) { System.Threading.Thread.Sleep(SLEEP_INTERVAL); t += SLEEP_INTERVAL; } if (t < UPLOAD_CONFIRM_TIMEOUT) { if (isMultiPacketUpload) { WaitingForUploadConfirm = true; } PendingUpload = upload; Client.Network.SendPacket(request); return upload.ID; } else { throw new Exception("Timeout waiting for previous asset upload to begin"); } } }
/// <summary> /// Used to force asset data into the PendingUpload property, ie: for raw terrain uploads /// </summary> /// <param name="assetData">An AssetUpload object containing the data to upload to the simulator</param> internal void SetPendingAssetUploadData(AssetUpload assetData) { lock (PendingUploadLock) PendingUpload = assetData; }
public AssetUploadEventArgs(AssetUpload upload) { this.m_Upload = upload; }
/// <summary>Process an incoming packet and raise the appropriate events</summary> /// <param name="sender">The sender</param> /// <param name="e">The EventArgs object containing the packet data</param> protected void RequestXferHandler(object sender, PacketReceivedEventArgs e) { if (PendingUpload == null) Logger.Log("Received a RequestXferPacket for an unknown asset upload", Helpers.LogLevel.Warning, Client); else { AssetUpload upload = PendingUpload; PendingUpload = null; WaitingForUploadConfirm = false; RequestXferPacket request = (RequestXferPacket)e.Packet; upload.XferID = request.XferID.ID; upload.Type = (AssetType)request.XferID.VFileType; UUID transferID = new UUID(upload.XferID); Transfers[transferID] = upload; // Send the first packet containing actual asset data SendNextUploadPacket(upload); } }
private void SendNextUploadPacket(AssetUpload upload) { SendXferPacketPacket send = new SendXferPacketPacket(); send.XferID.ID = upload.XferID; send.XferID.Packet = upload.PacketNum++; if (send.XferID.Packet == 0) { // The first packet reserves the first four bytes of the data for the // total length of the asset and appends 1000 bytes of data after that send.DataPacket.Data = new byte[1004]; Buffer.BlockCopy(Utils.IntToBytes(upload.Size), 0, send.DataPacket.Data, 0, 4); Buffer.BlockCopy(upload.AssetData, 0, send.DataPacket.Data, 4, 1000); upload.Transferred += 1000; lock (Transfers) { Transfers.Remove(upload.AssetID); Transfers[upload.ID] = upload; } } else if ((send.XferID.Packet + 1) * 1000 < upload.Size) { // This packet is somewhere in the middle of the transfer, or a perfectly // aligned packet at the end of the transfer send.DataPacket.Data = new byte[1000]; Buffer.BlockCopy(upload.AssetData, upload.Transferred, send.DataPacket.Data, 0, 1000); upload.Transferred += 1000; } else { // Special handler for the last packet which will be less than 1000 bytes int lastlen = upload.Size - ((int)send.XferID.Packet * 1000); send.DataPacket.Data = new byte[lastlen]; Buffer.BlockCopy(upload.AssetData, (int)send.XferID.Packet * 1000, send.DataPacket.Data, 0, lastlen); send.XferID.Packet |= (uint)0x80000000; // This signals the final packet upload.Transferred += lastlen; } Client.Network.SendPacket(send); }
/// <summary> /// Upload a terrain RAW file /// </summary> /// <param name="fileData">A byte array containing the encoded terrain data</param> /// <param name="fileName">The name of the file being uploaded</param> /// <returns>The Id of the transfer request</returns> public UUID UploadTerrain(byte[] fileData, string fileName) { AssetUpload upload = new AssetUpload(); upload.AssetData = fileData; upload.AssetType = AssetType.Unknown; upload.Size = fileData.Length; upload.ID = UUID.Random(); // Tell the library we have a pending file to upload Client.Assets.SetPendingAssetUploadData(upload); // Create and populate a list with commands specific to uploading a raw terrain file List<String> paramList = new List<string>(); paramList.Add("upload filename"); paramList.Add(fileName); // Tell the simulator we have a new raw file to upload Client.Estate.EstateOwnerMessage("terrain", paramList); return upload.ID; }
private void Assets_OnAssetUploaded(AssetUpload upload) { lock (PendingUploads) { if (PendingUploads.ContainsKey(upload.AssetID)) { if (upload.Success) { // Setup the TextureEntry with the new baked upload TextureIndex index = PendingUploads[upload.AssetID]; AgentTextures[(int)index] = upload.AssetID; Log.DebugLog("Upload complete, AgentTextures " + index.ToString() + " set to " + upload.AssetID.ToString()); } else { Log.Log("Asset upload " + upload.AssetID.ToString() + " failed", Helpers.LogLevel.Warning); } PendingUploads.Remove(upload.AssetID); Log.DebugLog("Pending uploads: " + PendingUploads.Count + ", pending downloads: " + ImageDownloads.Count); if (PendingUploads.Count == 0 && ImageDownloads.Count == 0) { Log.DebugLog("All pending image downloads and uploads complete"); CachedResponseEvent.Set(); } } else { // TEMP Log.DebugLog("Upload " + upload.AssetID.ToString() + " was not found in PendingUploads"); } } }
private void RequestXferHandler(Packet packet, Simulator simulator) { if (PendingUpload == null) Log.Log("Received a RequestXferPacket for an unknown asset upload", Helpers.LogLevel.Warning); else { AssetUpload upload = PendingUpload; PendingUpload = null; WaitingForUploadConfirm = false; RequestXferPacket request = (RequestXferPacket)packet; upload.XferID = request.XferID.ID; upload.Type = (AssetType)request.XferID.VFileType; UUID transferID = new UUID(upload.XferID); Transfers[transferID] = upload; // Send the first packet containing actual asset data SendNextUploadPacket(upload); } }
public void Assets_OnAssetUploaded(AssetUpload upload) { Hashtable hash = new Hashtable(); hash.Add("MessageType", "AssetUploaded"); hash.Add("AssetID", upload.AssetID); hash.Add("TransferID", upload.XferID); hash.Add("ID", upload.ID); hash.Add("Success", upload.Success); enqueue(hash); }