/// <summary> /// Set object media /// </summary> /// <param name="primID">UUID of the prim</param> /// <param name="faceMedia">Array the length of prims number of faces. Null on face indexes where there is /// no media, <seealso cref="MediaEntry"/> on faces which contain the media</param> /// <param name="sim">Simulatior in which prim is located</param> public void UpdateObjectMedia(UUID primID, MediaEntry[] faceMedia, Simulator sim) { Uri url; if (sim.Caps != null && null != (url = sim.Caps.CapabilityURI("ObjectMedia"))) { ObjectMediaUpdate req = new ObjectMediaUpdate(); req.PrimID = primID; req.FaceMedia = faceMedia; req.Verb = "UPDATE"; CapsClient request = new CapsClient(url); request.OnComplete += (CapsClient client, OSD result, Exception error) => { if (error != null) { Logger.Log("ObjectMediaUpdate: " + error.Message, Helpers.LogLevel.Error, Client); } }; request.BeginGetResponse(req.Serialize(), OSDFormat.Xml, Client.Settings.CAPS_TIMEOUT); } else { Logger.Log("ObjectMedia capability not available", Helpers.LogLevel.Error, Client); } }
/// <summary> /// Handle an update of media textures. /// </summary> /// <param name="path">Path on which this request was made</param> /// <param name="omu">/param> /// <returns></returns> protected string HandleObjectMediaUpdate(string path, ObjectMediaUpdate omu) { UUID primId = omu.PrimID; ISceneChildEntity part = m_scene.GetSceneObjectPart (primId); if (null == part) { m_log.WarnFormat( "[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}", primId, m_scene.RegionInfo.RegionName); return string.Empty; } // m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId); // for (int i = 0; i < omu.FaceMedia.Length; i++) // { // MediaEntry me = omu.FaceMedia[i]; // string v = (null == me ? "null": OSDParser.SerializeLLSDXmlString(me.GetOSD())); // m_log.DebugFormat("[MOAP]: Face {0} [{1}]", i, v); // } if (omu.FaceMedia.Length > part.GetNumberOfSides()) { m_log.WarnFormat( "[MOAP]: Received {0} media entries from client for prim {1} {2} but this prim has only {3} faces. Dropping request.", omu.FaceMedia.Length, part.Name, part.UUID, part.GetNumberOfSides()); return string.Empty; } UUID agentId = default(UUID); lock (m_omCapUsers) agentId = m_omCapUsers[path]; List<MediaEntry> media = part.Shape.Media; if (null == media) { // m_log.DebugFormat("[MOAP]: Setting all new media list for {0}", part.Name); part.Shape.Media = new PrimitiveBaseShape.MediaList(omu.FaceMedia); for (int i = 0; i < omu.FaceMedia.Length; i++) { if (omu.FaceMedia[i] != null) { // FIXME: Race condition here since some other texture entry manipulator may overwrite/get // overwritten. Unfortunately, PrimitiveBaseShape does not allow us to change texture entry // directly. SetPartMediaFlags(part, i, true); // m_log.DebugFormat( // "[MOAP]: Media flags for face {0} is {1}", // i, part.Shape.Textures.FaceTextures[i].MediaFlags); } } } else { // We need to go through the media textures one at a time to make sure that we have permission // to change them // FIXME: Race condition here since some other texture entry manipulator may overwrite/get // overwritten. Unfortunately, PrimitiveBaseShape does not allow us to change texture entry // directly. Primitive.TextureEntry te = part.Shape.Textures; lock (media) { for (int i = 0; i < media.Count; i++) { if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i)) { media[i] = omu.FaceMedia[i]; // When a face is cleared this is done by setting the MediaFlags in the TextureEntry via a normal // texture update, so we don't need to worry about clearing MediaFlags here. if (null == media[i]) continue; SetPartMediaFlags(part, i, true); // m_log.DebugFormat( // "[MOAP]: Media flags for face {0} is {1}", // i, face.MediaFlags); // m_log.DebugFormat("[MOAP]: Set media entry for face {0} on {1}", i, part.Name); } } } part.Shape.Textures = te; // for (int i2 = 0; i2 < part.Shape.Textures.FaceTextures.Length; i2++) // m_log.DebugFormat("[MOAP]: FaceTexture[{0}] is {1}", i2, part.Shape.Textures.FaceTextures[i2]); } UpdateMediaUrl(part, agentId); // Arguably, we could avoid sending a full update to the avatar that just changed the texture. part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); part.TriggerScriptChangedEvent(Changed.MEDIA); return string.Empty; }