public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) { Hashtable responsedata = new Hashtable(); responsedata["int_response_code"] = 400; //501; //410; //404; responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "Request wasn't what was expected"; UUID meshID = UUID.Zero; if ((request.ContainsKey("mesh_id")) && (UUID.TryParse(request["mesh_id"].ToString(), out meshID))) { if (m_AssetCache == null) { responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; return(responsedata); } AssetBase mesh = m_AssetCache.GetAsset(meshID, AssetRequestInfo.GenericNetRequest()); if (mesh != null) { if (mesh.Type == (SByte)AssetType.Mesh) { responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["int_response_code"] = 200; } // Optionally add additional mesh types here else { responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; return(responsedata); } } else { responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; return(responsedata); } } return(responsedata); }
public bool RequestUpdateTaskInventoryItem( IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) { AssetXferUploader uploader = GetTransactionUploader(transactionID); if (uploader == null) { m_log.WarnFormat("[ASSET TRANSACTIONS]: Transaction {0} NOT FOUND (duplicate removed?) for inventory item update {1}", transactionID, item.Name); return(false); } // This may complete now if upload complete, or later when the upload completes. uploader.TriggerWhenUploadComplete(delegate(AssetBase asset) { // This upload transaction is complete. XferUploaders.Remove(transactionID); if (asset == null) { return; // UpdateItem() not called } m_log.DebugFormat( "[ASSET TRANSACTIONS]: Updating task item {0} in {1} with asset in transaction {2}", item.Name, part.Name, transactionID); asset.Name = item.Name; asset.Description = item.Description; asset.Type = (sbyte)item.Type; try { Manager.MyScene.CommsManager.AssetCache.AddAsset(asset, AssetRequestInfo.GenericNetRequest()); if (part.Inventory.UpdateTaskInventoryItemAsset(part.UUID, item.ItemID, asset.FullID)) { part.GetProperties(remoteClient); } } catch (AssetServerException e) { remoteClient.SendAgentAlertMessage("Unable to upload asset. Please try again later.", false); m_log.ErrorFormat("[ASSET TRANSACTIONS] Unable to update task item due to asset server error {0}", e); } }); // We at least found an uploader with that transaction ID. return(true); }
/// <summary> /// Handle raw uploaded baked texture data. /// </summary> /// <param name="data"></param> /// <param name="path"></param> /// <param name="param"></param> /// <returns></returns> public string BakedTextureUploaded(byte[] data, string path, string param) { String result; bool decodeFailed = false; UUID newAssetID = UUID.Random(); if (data.Length <= 0) { m_log.ErrorFormat("[CAPS]: Invalid length {0} on UploadBakeRequestPut for {1}", data.Length, path); decodeFailed = true; } else if (m_layerDecoder != null) { decodeFailed = (m_layerDecoder.Decode(newAssetID, data) == false); } if (decodeFailed) { Hashtable badReply = new Hashtable(); badReply["state"] = "error"; badReply["new_asset"] = UUID.Zero; result = LLSDHelpers.SerializeLLSDReply(badReply); } else { AssetBase asset = new AssetBase(newAssetID, "Baked Texture", (sbyte)AssetType.Texture, m_Caps.AgentID.ToString()); asset.Data = data; //Persist baked textures as we will use them in the baked texture cache //asset.Temporary = true; asset.Local = true; m_assetCache.AddAsset(asset, AssetRequestInfo.GenericNetRequest()); LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); uploadComplete.new_asset = newAssetID.ToString(); uploadComplete.new_inventory_item = UUID.Zero; uploadComplete.state = "complete"; result = LLSDHelpers.SerializeLLSDReply(uploadComplete); // m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID); } m_Caps.HttpListener.RemoveStreamHandler("POST", m_uploaderPath); return(result); }
public bool RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) { AssetXferUploader uploader = GetTransactionUploader(transactionID); if (uploader == null) { m_log.WarnFormat("[ASSET TRANSACTIONS]: Transaction {0} NOT FOUND (duplicate removed?) for inventory item update {1}", transactionID, item.Name); return(false); } CachedUserInfo userInfo = Manager.MyScene.CommsManager.UserService.GetUserDetails(remoteClient.AgentId); if (userInfo == null) { m_log.WarnFormat("[ASSET TRANSACTIONS]: Could not find user {0} for transaction {1} for inventory update {2}", remoteClient.AgentId, transactionID, item.Name); return(false); } // This may complete now if upload complete, or later when the upload completes. uploader.TriggerWhenUploadComplete(delegate(AssetBase asset) { // This upload transaction is complete. XferUploaders.Remove(transactionID); UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId); if (asset == null || asset.FullID != assetID) { m_log.ErrorFormat("[ASSETS]: RequestUpdateInventoryItem wrong asset ID or not found {0}", asset == null ? "null" : asset.FullID.ToString()); return; } // Assets never get updated, new ones get created UUID oldID = asset.FullID; asset.FullID = UUID.Random(); asset.Name = item.Name; asset.Description = item.Description; asset.Type = (sbyte)item.AssetType; try { m_log.DebugFormat("[ASSETS]: RequestUpdateInventoryItem for transaction {0}, new asset {1} -> {2}", transactionID, oldID, asset.FullID); Manager.MyScene.CommsManager.AssetCache.AddAsset(asset, AssetRequestInfo.GenericNetRequest()); } catch (AssetServerException e) { remoteClient.SendAgentAlertMessage("Unable to upload asset. Please try again later.", false); m_log.ErrorFormat("[ASSET TRANSACTIONS] Creation of asset failed {0}", e); return; } item.AssetID = asset.FullID; //wait for completion of the write to avoid reversion ManualResetEventSlim waitEvent = new ManualResetEventSlim(); remoteClient.HandleWithInventoryWriteThread(() => { // Update the asset ID userInfo.UpdateItem(item); waitEvent.Set(); }); waitEvent.Wait(); waitEvent.Dispose(); }); return(true); // userInfo item was updated }
private void DoCreateItem(uint callbackID) { m_createItem = false; // don't create or bill for the same item more than once try { m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(m_asset, AssetRequestInfo.GenericNetRequest()); } catch (AssetServerException e) { ourClient.SendAgentAlertMessage("Unable to upload asset. Please try again later.", false); m_log.ErrorFormat("[ASSET TRANSACTIONS] Asset storage failed: {0}", e); return; } CachedUserInfo userInfo = m_userTransactions.Manager.MyScene.CommsManager.UserService.GetUserDetails( ourClient.AgentId); if (userInfo != null) { InventoryItemBase item = new InventoryItemBase(); item.Owner = ourClient.AgentId; item.CreatorId = ourClient.AgentId.ToString(); item.ID = UUID.Random(); item.AssetID = m_asset.FullID; item.Description = m_description; item.Name = m_name; item.AssetType = type; item.InvType = invType; item.Folder = InventFolder; item.BasePermissions = (uint)(PermissionMask.All | PermissionMask.Export); item.CurrentPermissions = (uint)(PermissionMask.All | PermissionMask.Export); item.GroupPermissions = (uint)PermissionMask.None; item.EveryOnePermissions = (uint)PermissionMask.None; item.NextPermissions = nextPerm; item.Flags = (uint)wearableType; item.CreationDate = Util.UnixTimeSinceEpoch(); userInfo.AddItem(item); ourClient.SendInventoryItemCreateUpdate(item, callbackID); // Charge for the upload if appropriate. IMoneyModule mm = ourClient.Scene.RequestModuleInterface <IMoneyModule>(); if (mm != null) { if (mm.UploadChargeApplies((AssetType)m_asset.Type) && !m_asset.Temporary) { mm.ApplyUploadCharge(ourClient.AgentId); } } } else { m_log.ErrorFormat("[ASSET TRANSACTIONS]: Could not find user {0} for inventory item creation", ourClient.AgentId); } }
protected void SendCompleteMessage() { m_finished = true; if (m_createItem) { DoCreateItem(m_createItemCallback); } else if (m_storeLocal) { try { m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(m_asset, AssetRequestInfo.GenericNetRequest()); } catch (AssetServerException e) { m_log.ErrorFormat("[ASSET TRANSACTIONS]: Error uploading asset data for transaction {0}", e); ourClient.SendAgentAlertMessage("Unable to upload asset. Please try again later.", false); ourClient.SendAssetUploadCompleteMessage(m_asset.Type, false, UUID.Zero); return; } } ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); m_log.DebugFormat("[ASSET TRANSACTIONS]: Uploaded asset data for transaction {0}", TransactionID); if (m_dumpAssetToFile) { DateTime now = DateTime.Now; string filename = String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, m_asset.Name, m_asset.Type); SaveAssetToFile(filename, m_asset.Data); } // Callback to the completion delegate if defined. if (m_assetUploadedDelegate != null) { TriggerWhenUploadComplete(m_assetUploadedDelegate); } }
public void RunUpdate() { //This is where we decide what we need to update //and assign the real discardLevel and packetNumber //assuming of course that the connected client might be bonkers if (!HasAsset) { if (!m_assetRequested) { m_assetRequested = true; AssetService.GetAsset(TextureID, AssetDataCallback, AssetRequestInfo.GenericNetRequest()); } } else { if (!IsDecoded) { //We need to decode the requested image first if (!m_decodeRequested) { //Request decode m_decodeRequested = true; // Do we have a jpeg decoder? if (J2KDecoder != null) { if (m_asset == null) { J2KDecodedCallback(TextureID, new OpenJPEG.J2KLayerInfo[0]); } else { // Send it off to the jpeg decoder J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback); } } else { J2KDecodedCallback(TextureID, new OpenJPEG.J2KLayerInfo[0]); } } } else { // Check for missing image asset data if (m_asset == null) { //m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing asset data (no missing image texture?). Canceling texture transfer"); m_currentPacket = m_stopPacket; return; } if (DiscardLevel >= 0 || m_stopPacket == 0) { // This shouldn't happen, but if it does, we really can't proceed if (Layers == null) { m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing Layers. Canceling texture transfer"); m_currentPacket = m_stopPacket; return; } int maxDiscardLevel = Math.Max(0, Layers.Length - 1); // Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel if (DiscardLevel < 0 && m_stopPacket == 0) { DiscardLevel = (sbyte)maxDiscardLevel; } // Clamp at the highest discard level DiscardLevel = (sbyte)Math.Min(DiscardLevel, maxDiscardLevel); //Calculate the m_stopPacket if (Layers.Length > 0) { m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - DiscardLevel].End); //I don't know why, but the viewer seems to expect the final packet if the file //is just one packet bigger. if (TexturePacketCount() == m_stopPacket + 1) { m_stopPacket = TexturePacketCount(); } } else { m_stopPacket = TexturePacketCount(); } m_currentPacket = StartPacket; } } } }
/// <summary> /// Handle a texture request. This involves creating a texture sender and placing it on the /// previously passed in shared queue. /// </summary> /// <param name="e"></param> public void HandleTextureRequest(TextureRequestArgs e) { TextureSender.TextureSender textureSender; //TODO: should be working out the data size/ number of packets to be sent for each discard level if ((e.DiscardLevel >= 0) || (e.Priority != 0)) { lock (m_textureSenders) { if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) { // If we've received new non UUID information for this request and it hasn't dispatched // yet, then update the request accordingly. textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber); } else { // m_log.DebugFormat("[TEXTURE]: Received a request for texture {0}", e.RequestedAssetID); if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) { // m_log.DebugFormat( // "[TEXTURE]: Refusing request for {0} from client {1}", // e.RequestedAssetID, m_client.AgentId); return; } else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) { if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID)) { if (StatsManager.SimExtraStats != null) { StatsManager.SimExtraStats.AddBlockedMissingTextureRequest(); } // Commenting out this message for now as it causes too much noise with other // debug messages. // m_log.DebugFormat( // "[TEXTURE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests", // e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS); } return; } m_scene.StatsReporter.AddPendingDownloads(1); TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber); m_textureSenders.Add(e.RequestedAssetID, requestHandler); m_scene.CommsManager.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, AssetRequestInfo.GenericNetRequest()); } } } else { lock (m_textureSenders) { if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) { textureSender.Cancel = true; } } } }