/// <summary> /// Sends a request for the next wearable asset. /// </summary> protected void RequestNextQueuedWearableAsset() { lock (WearableAssetQueue) { if (WearableAssetQueue.Count > 0) { AssetWearable wearableAsset = WearableCache[WearableAssetQueue[0]]; /*AssetRequestDownload request =*/ Client.Assets.RequestInventoryAsset(wearableAsset.AssetID, wearableAsset.Type); LogWearableAssetQueueActivity("Requesting: " + wearableAsset.AssetID); } else { if (AgentWearablesSignal.WaitOne(0, false) == true) { // Send updated AgentSetAppearance SendAgentSetAppearance(); } } } }
/// <summary> /// Updates the TextureEntry and Appearance Param structures with the data from an asset wearable. /// Called once for each weable asset. /// </summary> /// <param name="wearableAsset"></param> protected void UpdateAgentTextureEntryAndAppearanceParams(AssetWearable wearableAsset) { try { foreach (KeyValuePair <uint, LLUUID> texture in wearableAsset.Textures) { AgentTextureEntry.CreateFace(texture.Key).TextureID = texture.Value; } lock (AgentAppearanceParams) { foreach (KeyValuePair <int, float> kvp in wearableAsset.Parameters) { AgentAppearanceParams[kvp.Key] = kvp.Value; } } } catch (Exception e) { Client.Log(e.ToString() + Environment.NewLine + wearableAsset.AssetDataToString(), Helpers.LogLevel.Error); } }
/// <summary> /// Called each time a wearable asset is done downloading /// </summary> /// <param name="request"></param> void AManager_TransferRequestCompletedEvent(AssetRequest request) { if (!(request is AssetRequestDownload)) { return; } AssetRequestDownload dlrequest = (AssetRequestDownload)request; if (dlrequest.AssetID == null) { Client.Log("AssetID is null in AssetRequestDownload: " + dlrequest.StatusMsg, Helpers.LogLevel.Error); } WearableCacheQueueMutex.WaitOne(); // Remove from the download queue lock (WearableAssetQueue) { if (!WearableAssetQueue.Contains(dlrequest.AssetID)) { // Looks like we got an asset for something other then what we're waiting for, ignore it WearableCacheQueueMutex.ReleaseMutex(); return; } } // Since we got a response for this asset, remove it from the queue WearableAssetQueue.Remove(dlrequest.AssetID); LogWearableAssetQueueActivity("Received queued asset, and removed: " + dlrequest.AssetID); // If the request wasn't successful, then don't try to process it. if (request.Status != AssetRequest.RequestStatus.Success) { Client.Log("Error downloading wearable asset: " + dlrequest.AssetID, Helpers.LogLevel.Error); WearableCacheQueueMutex.ReleaseMutex(); return; } AssetWearable wearableAsset = WearableCache[dlrequest.AssetID]; wearableAsset.SetAssetData(dlrequest.GetAssetData()); if ((wearableAsset.AssetData == null) || (wearableAsset.AssetData.Length == 0)) { Client.Log("Asset retrieval failed for AssetID: " + wearableAsset.AssetID, Helpers.LogLevel.Error); WearableCacheQueueMutex.ReleaseMutex(); return; } else { UpdateAgentTextureEntryAndAppearanceParams(wearableAsset); UpdateAgentTextureEntryOrder(); lock (WearableAssetQueue) { if (WearableAssetQueue.Count > 0) { RequestNextQueuedWearableAsset(); WearableCacheQueueMutex.ReleaseMutex(); return; } } // Now that all the wearable assets are done downloading, // send an appearance packet SendAgentSetAppearance(); WearableCacheQueueMutex.ReleaseMutex(); return; } }
private void AgentWearablesUpdateCallbackHandler(Packet packet, Simulator simulator) { AgentWearablesUpdatePacket wearablesPacket = (AgentWearablesUpdatePacket)packet; AgentWearablesData = wearablesPacket.WearableData; AgentWearablesSignal.Set(); // Grab access mutex... WearableCacheQueueMutex.WaitOne(); // Queue download of wearables foreach (AgentWearablesUpdatePacket.WearableDataBlock wdb in AgentWearablesData) { // Don't try to download if AssetID is zero if (wdb.AssetID == LLUUID.Zero) { continue; } // Don't try to download, if it's already cached. if (WearableCache.ContainsKey(wdb.AssetID)) { AssetWearable aw = WearableCache[wdb.AssetID]; if (aw._AssetData != null) { continue; } } // Don't try to download, if it's already in the download queue lock (WearableAssetQueue) { if (WearableAssetQueue.Contains(wdb.AssetID)) { continue; } } AssetWearable wearableAsset; switch (wdb.WearableType) { case 0: case 1: case 2: case 3: wearableAsset = new AssetWearable_Body(wdb.AssetID, null); break; default: wearableAsset = new AssetWearable_Clothing(wdb.AssetID, null); break; } WearableCache[wdb.AssetID] = wearableAsset; lock (WearableAssetQueue) { if (!WearableAssetQueue.Contains(wdb.AssetID)) { WearableAssetQueue.Add(wdb.AssetID); LogWearableAssetQueueActivity("Added wearable asset to download queue: " + wearableAsset.GetType().Name + " : " + wdb.AssetID); } } } RequestNextQueuedWearableAsset(); WearableCacheQueueMutex.ReleaseMutex(); }