/// <summary> /// Add an item to this prim's inventory. /// </summary> /// <param name="name">The name that the new item should have.</param> /// <param name="item"> /// The item itself. The name within this structure is ignored in favour of the name /// given in this method's arguments /// </param> /// <param name="allowedDrop"> /// Item was only added to inventory because AllowedDrop is set /// </param> protected void AddInventoryItem(string name, TaskInventoryItem item, bool allowedDrop) { name = FindAvailableInventoryName(name); if (name == String.Empty) { return; } item.ParentID = m_part.UUID; item.ParentPartID = m_part.UUID; item.Name = name; item.GroupID = m_part.GroupID; lock (m_items) m_items.Add(item.ItemID, item); if (allowedDrop) { m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); } else { m_part.TriggerScriptChangedEvent(Changed.INVENTORY); } m_inventorySerial++; //m_inventorySerial += 2; HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; }
/// <summary> /// Set the media entry on the face of the given part. /// </summary> /// <param name="part">/param> /// <param name="face"></param> /// <param name="me">If null, then the media entry is cleared.</param> public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me) { // m_log.DebugFormat("[MOAP]: SetMediaEntry for {0}, face {1}", part.Name, face); CheckFaceParam(part, face); if (null == part.Shape.Media) { if (me == null) { return; } else { part.Shape.Media = new PrimitiveBaseShape.MediaList(new MediaEntry[part.GetNumberOfSides()]); } } lock (part.Shape.Media) part.Shape.Media[face] = me; UpdateMediaUrl(part, UUID.Zero); SetPartMediaFlags(part, face, me != null); part.ParentGroup.HasGroupChanged = true; part.ScheduleFullUpdate(); part.TriggerScriptChangedEvent(Changed.MEDIA); }
/// <summary> /// Set the media entry on the face of the given part. /// </summary> /// <param name="part">/param> /// <param name="face"></param> /// <param name="me">If null, then the media entry is cleared.</param> public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me) { // m_log.DebugFormat("[MOAP]: SetMediaEntry for {0}, face {1}", part.Name, face); int numFaces = part.GetNumberOfSides(); if (part.Shape.Media == null) { part.Shape.Media = new PrimitiveBaseShape.PrimMedia(numFaces); } else { part.Shape.Media.Resize(numFaces); } if (!CheckFaceParam(part, face)) { return; } // ClearMediaEntry passes null for me so it must not be ignored! lock (part.Shape.Media) part.Shape.Media[face] = me; UpdateMediaUrl(part, UUID.Zero); SetPartMediaFlags(part, face, me != null); part.ScheduleFullUpdate(PrimUpdateFlags.FindBest); part.TriggerScriptChangedEvent(Changed.MEDIA); }
public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me) { CheckFaceParam(part, face); if (null == part.Shape.Media) { part.Shape.Media = new PrimitiveBaseShape.MediaList(new MediaEntry[part.GetNumberOfSides()]); } lock (part.Shape.Media) part.Shape.Media[face] = me; UpdateMediaUrl(part, UUID.Zero); part.ScheduleFullUpdate(); part.TriggerScriptChangedEvent(Changed.MEDIA); }
public string RenderMaterialsPostCap(string request, UUID agentID) { OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); OSDMap resp = new OSDMap(); OSDMap materialsFromViewer = null; OSDArray respArr = new OSDArray(); if (req.ContainsKey("Zipped")) { OSD osd = null; byte[] inBytes = req["Zipped"].AsBinary(); try { osd = ZDecompressBytesToOsd(inBytes); if (osd != null) { if (osd is OSDArray) // assume array of MaterialIDs designating requested material entries { foreach (OSD elem in (OSDArray)osd) { try { UUID id = new UUID(elem.AsBinary(), 0); lock (m_regionMaterials) { if (m_regionMaterials.ContainsKey(id)) { OSDMap matMap = new OSDMap(); matMap["ID"] = OSD.FromBinary(id.GetBytes()); matMap["Material"] = m_regionMaterials[id]; respArr.Add(matMap); } else { m_log.Warn("[Materials]: request for unknown material ID: " + id.ToString()); // Theoretically we could try to load the material from the assets service, // but that shouldn't be necessary because the viewer should only request // materials that exist in a prim on the region, and all of these materials // are already stored in m_regionMaterials. } } } catch (Exception e) { m_log.Error("Error getting materials in response to viewer request", e); continue; } } } else if (osd is OSDMap) // request to assign a material { materialsFromViewer = osd as OSDMap; if (materialsFromViewer.ContainsKey("FullMaterialsPerFace")) { OSD matsOsd = materialsFromViewer["FullMaterialsPerFace"]; if (matsOsd is OSDArray) { OSDArray matsArr = matsOsd as OSDArray; try { foreach (OSDMap matsMap in matsArr) { uint primLocalID = 0; try { primLocalID = matsMap["ID"].AsUInteger(); } catch (Exception e) { m_log.Warn("[Materials]: cannot decode \"ID\" from matsMap: " + e.Message); continue; } OSDMap mat = null; try { mat = matsMap["Material"] as OSDMap; } catch (Exception e) { m_log.Warn("[Materials]: cannot decode \"Material\" from matsMap: " + e.Message); continue; } SceneObjectPart sop = m_scene.GetSceneObjectPart(primLocalID); if (sop == null) { m_log.WarnFormat("[Materials]: SOP not found for localId: {0}", primLocalID.ToString()); continue; } if (!m_scene.Permissions.CanEditObject(sop.UUID, agentID)) { m_log.WarnFormat("User {0} can't edit object {1} {2}", agentID, sop.Name, sop.UUID); continue; } Primitive.TextureEntry te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); if (te == null) { m_log.WarnFormat("[Materials]: Error in TextureEntry for SOP {0} {1}", sop.Name, sop.UUID); continue; } UUID id; if (mat == null) { // This happens then the user removes a material from a prim id = UUID.Zero; } else { id = StoreMaterialAsAsset(agentID, mat, sop); } int face = -1; if (matsMap.ContainsKey("Face")) { face = matsMap["Face"].AsInteger(); Primitive.TextureEntryFace faceEntry = te.CreateFace((uint)face); faceEntry.MaterialID = id; } else { if (te.DefaultTexture == null) { m_log.WarnFormat("[Materials]: TextureEntry.DefaultTexture is null in {0} {1}", sop.Name, sop.UUID); } else { te.DefaultTexture.MaterialID = id; } } //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually sop.Shape.TextureEntry = te.GetBytes(); if (sop.ParentGroup != null) { sop.TriggerScriptChangedEvent(Changed.TEXTURE); sop.UpdateFlag = UpdateRequired.FULL; sop.ParentGroup.HasGroupChanged = true; sop.ScheduleFullUpdate(); } } } catch (Exception e) { m_log.Warn("[Materials]: exception processing received material ", e); } } } } } } catch (Exception e) { m_log.Warn("[Materials]: exception decoding zipped CAP payload ", e); //return ""; } } resp["Zipped"] = ZCompressOSD(respArr, false); string response = OSDParser.SerializeLLSDXmlString(resp); //m_log.Debug("[Materials]: cap request: " + request); //m_log.Debug("[Materials]: cap request (zipped portion): " + ZippedOsdBytesToString(req["Zipped"].AsBinary())); //m_log.Debug("[Materials]: cap response: " + response); return(response); }
/// <summary> /// Received from the viewer if a user has changed the url of a media texture. /// </summary> /// <param name="request"></param> /// <param name="path"></param> /// <param name="param"></param> /// <param name="httpRequest">/param> /// <param name="httpResponse">/param> /// <returns></returns> protected void HandleObjectMediaNavigateMessage(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentId) { // m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request [{0}]", request); try { OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(httpRequest.InputStream); ObjectMediaNavigateMessage omn = new ObjectMediaNavigateMessage(); omn.Deserialize(osd); UUID primId = omn.PrimID; SceneObjectPart part = m_scene.GetSceneObjectPart(primId); bool bad = true; MediaEntry me = null; while (true) { if (null == part) { m_log.WarnFormat( "[MOAP]: Received an ObjectMediaNavigateMessage for prim {0} but this doesn't exist in region {1}", primId, m_scene.RegionInfo.RegionName); } if (!m_scene.Permissions.CanInteractWithPrimMedia(agentId, part.UUID, omn.Face)) { break; } //m_log.DebugFormat( // "[MOAP]: Received request to update media entry for face {0} on prim {1} {2} to {3}", // omn.Face, part.Name, part.UUID, omn.URL); // If media has never been set for this prim, then just return. if (null == part.Shape.Media) { break; } lock (part.Shape.Media) me = part.Shape.Media[omn.Face]; // Do the same if media has not been set up for a specific face if (null == me) { break; } if (me.EnableWhiteList) { if (!CheckUrlAgainstWhitelist(omn.URL, me.WhiteList)) { //m_log.DebugFormat( // "[MOAP]: Blocking change of face {0} on prim {1} {2} to {3} since it's not on the enabled whitelist", // omn.Face, part.Name, part.UUID, omn.URL); break; } } bad = false; break; } if (bad) { httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; return; } me.CurrentURL = omn.URL; UpdateMediaUrl(part, agentId); part.ParentGroup.HasGroupChanged = true; part.ScheduleFullUpdate(); part.TriggerScriptChangedEvent(Changed.MEDIA); httpResponse.RawBuffer = Util.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD())); httpResponse.StatusCode = (int)HttpStatusCode.OK; } catch { httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; httpResponse.RawBuffer = null; } }
/// <summary> /// Handle an update of media textures. /// </summary> /// <param name="omu">/param> /// <returns></returns> protected bool HandleObjectMediaUpdate(ObjectMediaUpdate omu, UUID agentId) { UUID primId = omu.PrimID; SceneObjectPart 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(false); } // 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(false); } 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 { // m_log.DebugFormat("[MOAP]: Setting existing media list for {0}", part.Name); // 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.ParentGroup.HasGroupChanged = true; part.ScheduleFullUpdate(); part.TriggerScriptChangedEvent(Changed.MEDIA); return(true); }
/// <summary> /// Received from the viewer if a user has changed the url of a media texture. /// </summary> /// <param name="request"></param> /// <param name="path"></param> /// <param name="param"></param> /// <param name="httpRequest">/param> /// <param name="httpResponse">/param> /// <returns></returns> protected string HandleObjectMediaNavigateMessage( string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { // m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request [{0}]", request); OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request); ObjectMediaNavigateMessage omn = new ObjectMediaNavigateMessage(); omn.Deserialize(osd); UUID primId = omn.PrimID; SceneObjectPart part = m_scene.GetSceneObjectPart(primId); if (null == part) { m_log.WarnFormat( "[MOAP]: Received an ObjectMediaNavigateMessage for prim {0} but this doesn't exist in region {1}", primId, m_scene.RegionInfo.RegionName); return(string.Empty); } UUID agentId = default(UUID); lock (m_omuCapUsers) agentId = m_omuCapUsers[path]; if (!m_scene.Permissions.CanInteractWithPrimMedia(agentId, part.UUID, omn.Face)) { return(string.Empty); } // m_log.DebugFormat( // "[MOAP]: Received request to update media entry for face {0} on prim {1} {2} to {3}", // omn.Face, part.Name, part.UUID, omn.URL); // If media has never been set for this prim, then just return. if (null == part.Shape.Media) { return(string.Empty); } MediaEntry me = null; lock (part.Shape.Media) me = part.Shape.Media[omn.Face]; // Do the same if media has not been set up for a specific face if (null == me) { return(string.Empty); } if (me.EnableWhiteList) { if (!CheckUrlAgainstWhitelist(omn.URL, me.WhiteList)) { // m_log.DebugFormat( // "[MOAP]: Blocking change of face {0} on prim {1} {2} to {3} since it's not on the enabled whitelist", // omn.Face, part.Name, part.UUID, omn.URL); return(string.Empty); } } me.CurrentURL = omn.URL; UpdateMediaUrl(part, agentId); part.ScheduleFullUpdate(); part.TriggerScriptChangedEvent(Changed.MEDIA); return(OSDParser.SerializeLLSDXmlString(new OSD())); }
public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) { SceneObjectPart part = m_scene.GetSceneObjectPart(localID); if (part == null) { return(false); } SceneObjectGroup group = part.ParentGroup; switch (saleType) { case 1: // Sell as original (in-place sale) uint effectivePerms = group.GetEffectivePermissions(); if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } group.SetOwnerId(remoteClient.AgentId); group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); if (m_scene.Permissions.PropagatePermissions()) { foreach (SceneObjectPart child in group.Parts) { child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } } part.ObjectSaleType = 0; part.SalePrice = 10; group.HasGroupChanged = true; part.SendPropertiesToClient(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); part.ScheduleFullUpdate(); break; case 2: // Sell a copy Vector3 inventoryStoredPosition = new Vector3( Math.Min(group.AbsolutePosition.X, m_scene.RegionInfo.RegionSizeX - 6), Math.Min(group.AbsolutePosition.Y, m_scene.RegionInfo.RegionSizeY - 6), group.AbsolutePosition.Z); Vector3 originalPosition = group.AbsolutePosition; group.AbsolutePosition = inventoryStoredPosition; string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); group.AbsolutePosition = originalPosition; uint perms = group.GetEffectivePermissions(); if ((perms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } AssetBase asset = m_scene.CreateAsset( group.GetPartName(localID), group.GetPartDescription(localID), (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), group.OwnerID); m_scene.AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase(); item.CreatorId = part.CreatorID.ToString(); item.CreatorData = part.CreatorData; item.ID = UUID.Random(); item.Owner = remoteClient.AgentId; item.AssetID = asset.FullID; item.Description = asset.Description; item.Name = asset.Name; item.AssetType = asset.Type; item.InvType = (int)InventoryType.Object; item.Folder = categoryID; PermissionsUtil.ApplyFoldedPermissions(perms, ref perms); item.BasePermissions = perms & part.NextOwnerMask; item.CurrentPermissions = perms & part.NextOwnerMask; item.NextPermissions = part.NextOwnerMask; item.EveryOnePermissions = part.EveryoneMask & part.NextOwnerMask; item.GroupPermissions = part.GroupMask & part.NextOwnerMask; item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; item.CreationDate = Util.UnixTimeSinceEpoch(); if (m_scene.AddInventoryItem(item)) { remoteClient.SendInventoryItemCreateUpdate(item, 0); } else { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable"); } return(false); } break; case 3: // Sell contents List <UUID> invList = part.Inventory.GetInventoryList(); bool okToSell = true; foreach (UUID invID in invList) { TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invID); if ((item1.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) { okToSell = false; break; } } if (!okToSell) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser( remoteClient, "This item's inventory doesn't appear to be for sale"); } return(false); } if (invList.Count > 0) { m_scene.MoveTaskInventoryItems(remoteClient.AgentId, part.Name, part, invList); } break; } return(true); }
public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) { SceneObjectPart part = m_scene.GetSceneObjectPart(localID); if (part == null) { return(false); } SceneObjectGroup group = part.ParentGroup; if (group == null || group.IsDeleted || group.inTransit) { return(false); } // make sure we are not buying a child part part = group.RootPart; switch (saleType) { case 1: // Sell as original (in-place sale) uint effectivePerms = group.EffectiveOwnerPerms; if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } group.SetOwner(remoteClient.AgentId, remoteClient.ActiveGroupId); if (m_scene.Permissions.PropagatePermissions()) { foreach (SceneObjectPart child in group.Parts) { child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } group.InvalidateDeepEffectivePerms(); } part.ObjectSaleType = 0; part.SalePrice = 10; part.ClickAction = Convert.ToByte(0); group.HasGroupChanged = true; part.SendPropertiesToClient(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); part.ScheduleFullUpdate(); break; case 2: // Sell a copy uint perms = group.EffectiveOwnerPerms; if ((perms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } if ((perms & (uint)PermissionMask.Copy) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This sale has been blocked by the permissions system"); } return(false); } string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); AssetBase asset = m_scene.CreateAsset( group.GetPartName(localID), group.GetPartDescription(localID), (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), group.OwnerID); m_scene.AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase(); item.CreatorId = part.CreatorID.ToString(); item.CreatorData = part.CreatorData; item.ID = UUID.Random(); item.Owner = remoteClient.AgentId; item.AssetID = asset.FullID; item.Description = asset.Description; item.Name = asset.Name; item.AssetType = asset.Type; item.InvType = (int)InventoryType.Object; item.Folder = categoryID; perms = group.CurrentAndFoldedNextPermissions(); // apply parts inventory next perms PermissionsUtil.ApplyNoModFoldedPermissions(perms, ref perms); // change to next owner perms perms &= part.NextOwnerMask; // update folded perms = PermissionsUtil.FixAndFoldPermissions(perms); item.BasePermissions = perms; item.CurrentPermissions = perms; item.NextPermissions = part.NextOwnerMask & perms; item.EveryOnePermissions = part.EveryoneMask & perms; item.GroupPermissions = part.GroupMask & perms; item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; item.CreationDate = Util.UnixTimeSinceEpoch(); if (m_scene.AddInventoryItem(item)) { remoteClient.SendInventoryItemCreateUpdate(item, 0); } else { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable"); } return(false); } break; case 3: // Sell contents List <UUID> invList = part.Inventory.GetInventoryList(); bool okToSell = true; foreach (UUID invID in invList) { TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invID); if ((item1.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) { okToSell = false; break; } } if (!okToSell) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser( remoteClient, "This item's inventory doesn't appear to be for sale"); } return(false); } if (invList.Count > 0) { m_scene.MoveTaskInventoryItems(remoteClient.AgentId, part.Name, part, invList); } break; } return(true); }
public void RenderMaterialsPutCap(IOSHttpRequest request, IOSHttpResponse response, UUID agentID) { OSDMap req; try { req = (OSDMap)OSDParser.DeserializeLLSDXml(request.InputStream); } catch { response.StatusCode = (int)HttpStatusCode.BadRequest; return; } OSDMap materialsFromViewer = null; OSDArray respArr = new OSDArray(); OSD tmpOSD; HashSet <SceneObjectPart> parts = new HashSet <SceneObjectPart>(); if (req.TryGetValue("Zipped", out tmpOSD)) { OSD osd = null; byte[] inBytes = tmpOSD.AsBinary(); try { osd = ZDecompressBytesToOsd(inBytes); if (osd != null && osd is OSDMap) { materialsFromViewer = osd as OSDMap; if (materialsFromViewer.TryGetValue("FullMaterialsPerFace", out tmpOSD) && (tmpOSD is OSDArray)) { OSDArray matsArr = tmpOSD as OSDArray; try { foreach (OSDMap matsMap in matsArr) { uint primLocalID = 0; try { primLocalID = matsMap["ID"].AsUInteger(); } catch (Exception e) { m_log.Warn("[Materials]: cannot decode \"ID\" from matsMap: " + e.Message); continue; } SceneObjectPart sop = m_scene.GetSceneObjectPart(primLocalID); if (sop == null) { m_log.WarnFormat("[Materials]: SOP not found for localId: {0}", primLocalID.ToString()); continue; } if (!m_scene.Permissions.CanEditObject(sop.UUID, agentID)) { m_log.WarnFormat("User {0} can't edit object {1} {2}", agentID, sop.Name, sop.UUID); continue; } OSDMap mat = null; try { mat = matsMap["Material"] as OSDMap; } catch (Exception e) { m_log.Warn("[Materials]: cannot decode \"Material\" from matsMap: " + e.Message); continue; } Primitive.TextureEntry te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); if (te == null) { m_log.WarnFormat("[Materials]: Error in TextureEntry for SOP {0} {1}", sop.Name, sop.UUID); continue; } int face = -1; UUID oldid = UUID.Zero; Primitive.TextureEntryFace faceEntry = null; if (matsMap.TryGetValue("Face", out tmpOSD)) { face = tmpOSD.AsInteger(); faceEntry = te.CreateFace((uint)face); } else { faceEntry = te.DefaultTexture; } if (faceEntry == null) { continue; } UUID id; FaceMaterial newFaceMat = null; if (mat == null) { // This happens then the user removes a material from a prim id = UUID.Zero; } else { newFaceMat = new FaceMaterial(mat); if (newFaceMat.DiffuseAlphaMode == 1 && newFaceMat.NormalMapID == UUID.Zero && newFaceMat.SpecularMapID == UUID.Zero ) { id = UUID.Zero; } else { newFaceMat.genID(); id = newFaceMat.ID; } } oldid = faceEntry.MaterialID; if (oldid == id) { continue; } if (faceEntry != null) { faceEntry.MaterialID = id; //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually sop.Shape.TextureEntry = te.GetBytes(9); } if (oldid != UUID.Zero) { RemoveMaterial(oldid); } lock (materialslock) { if (id != UUID.Zero) { if (m_Materials.ContainsKey(id)) { m_MaterialsRefCount[id]++; } else { m_Materials[id] = newFaceMat; m_MaterialsRefCount[id] = 1; m_changed[newFaceMat] = Util.GetTimeStamp(); } } } if (!parts.Contains(sop)) { parts.Add(sop); } } foreach (SceneObjectPart sop in parts) { if (sop.ParentGroup != null && !sop.ParentGroup.IsDeleted) { sop.TriggerScriptChangedEvent(Changed.TEXTURE); sop.ScheduleFullUpdate(); sop.ParentGroup.HasGroupChanged = true; } } } catch (Exception e) { m_log.Warn("[Materials]: exception processing received material ", e); response.StatusCode = (int)HttpStatusCode.BadRequest; return; } } } } catch (Exception e) { m_log.Warn("[Materials]: exception decoding zipped CAP payload ", e); response.StatusCode = (int)HttpStatusCode.BadRequest; return; } } OSDMap resp = new OSDMap(); resp["Zipped"] = ZCompressOSD(respArr, false); response.RawBuffer = Encoding.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(resp)); //m_log.Debug("[Materials]: cap request: " + request); //m_log.Debug("[Materials]: cap request (zipped portion): " + ZippedOsdBytesToString(req["Zipped"].AsBinary())); //m_log.Debug("[Materials]: cap response: " + response); }
public string RenderMaterialsPutCap(string request, UUID agentID) { OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); OSDMap resp = new OSDMap(); OSDMap materialsFromViewer = null; OSDArray respArr = new OSDArray(); HashSet <SceneObjectPart> parts = new HashSet <SceneObjectPart>(); if (req.ContainsKey("Zipped")) { OSD osd = null; byte[] inBytes = req["Zipped"].AsBinary(); try { osd = ZDecompressBytesToOsd(inBytes); if (osd != null && osd is OSDMap) { materialsFromViewer = osd as OSDMap; if (materialsFromViewer.ContainsKey("FullMaterialsPerFace")) { OSD matsOsd = materialsFromViewer["FullMaterialsPerFace"]; if (matsOsd is OSDArray) { OSDArray matsArr = matsOsd as OSDArray; try { foreach (OSDMap matsMap in matsArr) { uint primLocalID = 0; try { primLocalID = matsMap["ID"].AsUInteger(); } catch (Exception e) { m_log.Warn("[Materials]: cannot decode \"ID\" from matsMap: " + e.Message); continue; } SceneObjectPart sop = m_scene.GetSceneObjectPart(primLocalID); if (sop == null) { m_log.WarnFormat("[Materials]: SOP not found for localId: {0}", primLocalID.ToString()); continue; } if (!m_scene.Permissions.CanEditObject(sop.UUID, agentID)) { m_log.WarnFormat("User {0} can't edit object {1} {2}", agentID, sop.Name, sop.UUID); continue; } OSDMap mat = null; try { mat = matsMap["Material"] as OSDMap; } catch (Exception e) { m_log.Warn("[Materials]: cannot decode \"Material\" from matsMap: " + e.Message); continue; } Primitive.TextureEntry te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); if (te == null) { m_log.WarnFormat("[Materials]: Error in TextureEntry for SOP {0} {1}", sop.Name, sop.UUID); continue; } UUID id; if (mat == null) { // This happens then the user removes a material from a prim id = UUID.Zero; } else { id = getNewID(mat); } int face = -1; UUID oldid = UUID.Zero; if (matsMap.ContainsKey("Face")) { face = matsMap["Face"].AsInteger(); Primitive.TextureEntryFace faceEntry = te.CreateFace((uint)face); oldid = faceEntry.MaterialID; faceEntry.MaterialID = id; } else { if (te.DefaultTexture == null) { m_log.WarnFormat("[Materials]: TextureEntry.DefaultTexture is null in {0} {1}", sop.Name, sop.UUID); } else { oldid = te.DefaultTexture.MaterialID; te.DefaultTexture.MaterialID = id; } } //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually sop.Shape.TextureEntry = te.GetBytes(); lock (m_Materials) { if (oldid != UUID.Zero && m_MaterialsRefCount.ContainsKey(oldid)) { m_MaterialsRefCount[oldid]--; if (m_MaterialsRefCount[oldid] <= 0) { m_Materials.Remove(oldid); m_MaterialsRefCount.Remove(oldid); m_cache.Expire(oldid.ToString()); } } if (id != UUID.Zero) { AssetBase asset = CacheMaterialAsAsset(id, agentID, mat, sop); if (asset != null) { ulong materialHash = (ulong)primLocalID << 32; if (face < 0) { materialHash += 0xffffffff; } else { materialHash += (ulong)face; } m_changes[materialHash] = asset; m_changesTime[materialHash] = Util.GetTimeStampMS(); } } } if (!parts.Contains(sop)) { parts.Add(sop); } } foreach (SceneObjectPart sop in parts) { if (sop.ParentGroup != null && !sop.ParentGroup.IsDeleted) { sop.TriggerScriptChangedEvent(Changed.TEXTURE); sop.ScheduleFullUpdate(); sop.ParentGroup.HasGroupChanged = true; } } } catch (Exception e) { m_log.Warn("[Materials]: exception processing received material ", e); } } } } } catch (Exception e) { m_log.Warn("[Materials]: exception decoding zipped CAP payload ", e); //return ""; } } resp["Zipped"] = ZCompressOSD(respArr, false); string response = OSDParser.SerializeLLSDXmlString(resp); //m_log.Debug("[Materials]: cap request: " + request); //m_log.Debug("[Materials]: cap request (zipped portion): " + ZippedOsdBytesToString(req["Zipped"].AsBinary())); //m_log.Debug("[Materials]: cap response: " + response); return(response); }