/// <summary> /// Start a script which is in this prim's inventory. /// </summary> /// <param name="item"></param> /// <returns></returns> public void CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource) { // m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}", // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) { return; } m_part.AddFlag(PrimFlags.Scripted); if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) { if (stateSource == 2 && // Prim crossing m_part.ParentGroup.Scene.m_trustBinaries) { lock (m_items) { m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; } m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); return; } AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); if (null == asset) { m_log.ErrorFormat( "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", item.Name, item.ItemID, m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); } else { if (m_part.ParentGroup.m_savedScriptState != null) { item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); } lock (m_items) { m_items[item.ItemID].OldItemID = item.OldItemID; m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; } string script = Utils.BytesToString(asset.Data); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); } } }
/// <summary> /// Start a script which is in this prim's inventory. /// </summary> /// <param name="item"></param> /// <returns></returns> public void CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource) { // m_log.InfoFormat( // "[PRIM INVENTORY]: " + // "Starting script {0}, {1} in prim {2}, {3}", // item.Name, item.ItemID, Name, UUID); if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) { return; } m_part.AddFlag(PrimFlags.Scripted); if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) { if (stateSource == 1 && // Prim crossing m_part.ParentGroup.Scene.m_trustBinaries) { m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); return; } IAssetCache cache = m_part.ParentGroup.Scene.CommsManager.AssetCache; cache.GetAsset(item.AssetID, delegate(UUID assetID, AssetBase asset) { if (null == asset) { m_log.ErrorFormat( "[PRIM INVENTORY]: " + "Couldn't start script {0}, {1} since asset ID {2} could not be found", item.Name, item.ItemID, item.AssetID); } else { if (m_part.ParentGroup.m_savedScriptState != null) { RestoreSavedScriptState(item.OldItemID, item.ItemID); } m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; string script = Utils.BytesToString(asset.Data); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); } }, false); } }
private void growTrees() { foreach (Copse copse in m_copse) { if (!copse.m_frozen) { foreach (UUID tree in copse.m_trees) { if (m_scene.Entities.ContainsKey(tree)) { SceneObjectPart s_tree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; if (s_tree.Scale.X < copse.m_maximum_scale.X && s_tree.Scale.Y < copse.m_maximum_scale.Y && s_tree.Scale.Z < copse.m_maximum_scale.Z) { s_tree.Scale += copse.m_rate; s_tree.ParentGroup.HasGroupChanged = true; s_tree.ScheduleFullUpdate(); } } else { m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree); } } } } }
/// <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); }
private static void StopSound(SceneObjectPart m_host) { m_host.Sound = UUID.Zero; m_host.SoundFlags = (byte)SoundFlags.STOP; m_host.SoundGain = 0; m_host.ScheduleFullUpdate(); m_host.SendFullUpdateToAllClients(); }
private void growTrees() { if (!m_allowGrow) { return; } foreach (Copse copse in m_copses) { if (copse.m_frozen) { continue; } if (copse.m_trees.Count == 0) { continue; } float maxscale = copse.m_maximum_scale.Z; float ratescale = 1.0f; List <UUID> losttrees = new List <UUID>(); foreach (UUID tree in copse.m_trees) { SceneObjectGroup sog = m_scene.GetSceneObjectGroup(tree); if (sog != null && !sog.IsDeleted) { SceneObjectPart s_tree = sog.RootPart; if (s_tree.Scale.Z < maxscale) { ratescale = (float)Util.RandomClass.NextDouble(); if (ratescale < 0.2f) { ratescale = 0.2f; } s_tree.Scale += copse.m_rate * ratescale; sog.HasGroupChanged = true; s_tree.ScheduleFullUpdate(); } } else { losttrees.Add(tree); } } foreach (UUID tree in losttrees) { copse.m_trees.Remove(tree); } } }
private void InformPrimOfTransactionEnd(uint id, bool postUpdates) { SceneObjectPart part = _parent.GetSceneObjectPart(id); if (part != null) { part.IsInTransaction = false; if (!part.ParentGroup.IsDeleted && postUpdates) { part.ScheduleFullUpdate(); } } }
private static void StopSound(SceneObjectPart m_host) { m_host.AdjustSoundGain(0); // Xantor 20080528: Clear prim data of sound instead if (m_host.ParentGroup.LoopSoundSlavePrims.Contains(m_host)) { if (m_host.ParentGroup.LoopSoundMasterPrim == m_host) { foreach (SceneObjectPart part in m_host.ParentGroup.LoopSoundSlavePrims) { part.Sound = UUID.Zero; part.SoundFlags = 1 << 5; part.SoundRadius = 0; part.ScheduleFullUpdate(); part.SendFullUpdateToAllClients(); } m_host.ParentGroup.LoopSoundMasterPrim = null; m_host.ParentGroup.LoopSoundSlavePrims.Clear(); } else { m_host.Sound = UUID.Zero; m_host.SoundFlags = 1 << 5; m_host.SoundRadius = 0; m_host.ScheduleFullUpdate(); m_host.SendFullUpdateToAllClients(); } } else { m_host.Sound = UUID.Zero; m_host.SoundFlags = 1 << 5; m_host.SoundRadius = 0; m_host.ScheduleFullUpdate(); m_host.SendFullUpdateToAllClients(); } }
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 void PlaybackState(SceneObjectPart part) { if (part != null) { part.Undoing = true; if (part.ParentID == 0) { if (Position != Vector3.Zero) { part.ParentGroup.AbsolutePosition = Position; } part.RotationOffset = Rotation; if (Scale != Vector3.Zero) { part.Scale = Scale; } lock (part.ParentGroup.Children) { foreach (SceneObjectPart child in part.ParentGroup.Children.Values.Where(child => child.UUID != part.UUID)) { child.Undo(); //No updates here, child undo will do it on their own } } } else { if (Position != Vector3.Zero) { part.OffsetPosition = Position; } part.UpdateRotation(Rotation); if (Scale != Vector3.Zero) { part.Resize(Scale); } } part.Undoing = false; part.ScheduleFullUpdate(); } }
private void growTrees() { foreach (UUID tree in m_trees) { if (m_scene.Entities.ContainsKey(tree)) { SceneObjectPart s_tree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; // 100 seconds to grow 1m s_tree.Scale += new Vector3(0.1f, 0.1f, 0.1f); s_tree.ScheduleFullUpdate(PrimUpdateFlags.FindBest); //s_tree.ScheduleTerseUpdate(); } else { m_trees.Remove(tree); } } }
public void PlayfwdState(SceneObjectPart part) { if (part != null) { part.Undoing = true; if (part.ParentID == 0) { if (Position != Vector3.Zero) { part.ParentGroup.AbsolutePosition = Position; } part.RotationOffset = Rotation; if (Scale != Vector3.Zero) { part.Scale = Scale; } foreach (SceneObjectPart child in part.ParentGroup.GetParts().Where(child => child.UUID != part.UUID)) { child.Redo(); //No updates here, child redo will do it on their own } } else { if (Position != Vector3.Zero) { part.OffsetPosition = Position; } part.UpdateRotation(Rotation); if (Scale != Vector3.Zero) { part.Resize(Scale); } } part.Undoing = false; part.ScheduleFullUpdate(PrimUpdateFlags.FindBest); } }
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); }
public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId) { if (!Enabled) { return; } // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", // sp.UUID, soLocalId); SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); if (so == null) { return; } if (so.AttachedAvatar != sp.UUID) { return; } UUID inventoryID = so.GetFromItemID(); // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", // so.Name, so.LocalId, inventoryID); lock (sp.AttachmentsSyncLock) { if (!m_scene.Permissions.CanRezObject( so.PrimCount, sp.UUID, sp.AbsolutePosition)) { return; } bool changed = sp.Appearance.DetachAttachment(inventoryID); if (changed && m_scene.AvatarFactory != null) { m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); } sp.RemoveAttachment(so); SceneObjectPart rootPart = so.RootPart; rootPart.FromItemID = UUID.Zero; so.AbsolutePosition = sp.AbsolutePosition; so.AttachedAvatar = UUID.Zero; rootPart.SetParentLocalId(0); so.ClearPartAttachmentData(); rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); so.HasGroupChanged = true; rootPart.Rezzed = DateTime.Now; rootPart.RemFlag(PrimFlags.TemporaryOnRez); so.AttachToBackup(); m_scene.EventManager.TriggerParcelPrimCountTainted(); rootPart.ScheduleFullUpdate(); rootPart.ClearUndoState(); List <UUID> uuids = new List <UUID>(); uuids.Add(inventoryID); m_scene.InventoryService.DeleteItems(sp.UUID, uuids); sp.ControllingClient.SendRemoveInventoryItem(inventoryID); } m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); }
/// <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())); }
/// <summary> /// Called once new texture data has been received for this updater. /// </summary> public void DataReceived(byte[] data, Scene scene) { SceneObjectPart part = scene.GetSceneObjectPart(PrimID); if (data == null) { string msg = String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); return; } byte[] assetData; AssetBase oldAsset = null; if (BlendWithOldTexture) { UUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID; oldAsset = scene.CommsManager.AssetCache.GetAsset(lastTextureID, AssetRequestInfo.InternalRequest()); if (oldAsset != null) { assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); } else { assetData = new byte[data.Length]; Array.Copy(data, assetData, data.Length); } } else { assetData = new byte[data.Length]; Array.Copy(data, assetData, data.Length); } // Create a new asset for user AssetBase asset = new AssetBase(); asset.FullID = UUID.Random(); asset.Data = assetData; asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); asset.Type = 0; asset.Description = "dynamic image"; asset.Local = false; asset.Temporary = true; scene.CommsManager.AssetCache.AddAsset(asset, AssetRequestInfo.InternalRequest()); LastAssetID = asset.FullID; IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface <IJ2KDecoder>(); if (cacheLayerDecode != null) { cacheLayerDecode.Decode(asset.FullID, asset.Data); } cacheLayerDecode = null; // mostly keep the values from before Primitive.TextureEntry tmptex = part.Shape.Textures; // remove the old asset from the cache UUID oldID = tmptex.DefaultTexture.TextureID; tmptex.DefaultTexture.TextureID = asset.FullID; // I'm pretty sure we always want to force this to true // I'm pretty sure noone whats to set fullbright true if it wasn't true before. // tmptex.DefaultTexture.Fullbright = true; part.Shape.Textures = tmptex; part.ScheduleFullUpdate(); }
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); }
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 virtual SceneObjectGroup RezObject( IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); if (rezAsset == null) { if (item != null) { m_log.WarnFormat( "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", assetID, item.Name, item.ID, remoteClient.Name); remoteClient.SendAgentAlertMessage(string.Format("Unable to rez: could not find asset {0} for item {1}.", assetID, item.Name), false); } else { m_log.WarnFormat( "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()", assetID, remoteClient.Name); remoteClient.SendAgentAlertMessage(string.Format("Unable to rez: could not find asset {0}.", assetID), false); } return(null); } SceneObjectGroup group = null; List <SceneObjectGroup> objlist; List <Vector3> veclist; Vector3 bbox; float offsetHeight; byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); Vector3 pos; bool single = m_Scene.GetObjectsToRez( rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); if (single) { pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, bbox, false); pos.Z += offsetHeight; } else { pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, bbox, false); pos -= bbox / 2; } if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) { return(null); } for (int i = 0; i < objlist.Count; i++) { group = objlist[i]; // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); // Vector3 storedPosition = group.AbsolutePosition; if (group.UUID == UUID.Zero) { m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); } // if this was previously an attachment and is now being rezzed, // save the old attachment info. if (group.IsAttachment == false && group.RootPart.Shape.State != 0) { group.RootPart.AttachedPos = group.AbsolutePosition; group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; } if (item == null) { // Change ownership. Normally this is done in DoPreRezWhenFromItem(), but in this case we must do it here. foreach (SceneObjectPart part in group.Parts) { // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. part.LastOwnerID = part.OwnerID; part.OwnerID = remoteClient.AgentId; } } if (!attachment) { // If it's rezzed in world, select it. Much easier to // find small items. // foreach (SceneObjectPart part in group.Parts) { part.CreateSelected = true; } } group.ResetIDs(); if (attachment) { group.RootPart.Flags |= PrimFlags.Phantom; group.IsAttachment = true; } // If we're rezzing an attachment then don't ask // AddNewSceneObject() to update the client since // we'll be doing that later on. Scheduling more than // one full update during the attachment // process causes some clients to fail to display the // attachment properly. m_Scene.AddNewSceneObject(group, !attachment, false); // if attachment we set it's asset id so object updates // can reflect that, if not, we set it's position in world. if (!attachment) { group.ScheduleGroupForFullUpdate(); group.AbsolutePosition = pos + veclist[i]; } group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if (!attachment) { SceneObjectPart rootPart = group.RootPart; if (rootPart.Shape.PCode == (byte)PCode.Prim) { group.ClearPartAttachmentData(); } // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); rootPart.ParentGroup.ResumeScripts(); rootPart.ScheduleFullUpdate(); } // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); } if (item != null) { DoPostRezWhenFromItem(item, attachment); } return(group); }
/// <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> /// Rez an object into the scene from the user's inventory /// </summary> /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing /// things to the scene. The caller should be doing that, I think. /// <param name="remoteClient"></param> /// <param name="itemID"></param> /// <param name="RayEnd"></param> /// <param name="RayStart"></param> /// <param name="RayTargetID"></param> /// <param name="BypassRayCast"></param> /// <param name="RayEndIsIntersection"></param> /// <param name="RezSelected"></param> /// <param name="RemoveItem"></param> /// <param name="fromTaskID"></param> /// <param name="attachment"></param> /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns> public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { // Work out position details byte bRayEndIsIntersection = (byte)0; if (RayEndIsIntersection) { bRayEndIsIntersection = (byte)1; } else { bRayEndIsIntersection = (byte)0; } Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); Vector3 pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, scale, false); // Rez object InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_Scene.InventoryService.GetItem(item); if (item != null) { AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); if (rezAsset != null) { UUID itemId = UUID.Zero; // If we have permission to copy then link the rezzed object back to the user inventory // item that it came from. This allows us to enable 'save object to inventory' if (!m_Scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy) { itemId = item.ID; } } else { // Brave new fullperm world // itemId = item.ID; } string xmlData = Utils.BytesToString(rezAsset.Data); SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); if (!m_Scene.Permissions.CanRezObject( group.Children.Count, remoteClient.AgentId, pos) && !attachment) { // The client operates in no fail mode. It will // have already removed the item from the folder // if it's no copy. // Put it back if it's not an attachment // if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) { remoteClient.SendBulkUpdateInventory(item); } return(null); } group.ResetIDs(); if (attachment) { group.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom; group.RootPart.IsAttachment = true; } // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since // we'll be doing that later on. Scheduling more than one full update during the attachment // process causes some clients to fail to display the attachment properly. m_Scene.AddNewSceneObject(group, true, false); // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); // if attachment we set it's asset id so object updates can reflect that // if not, we set it's position in world. if (!attachment) { group.ScheduleGroupForFullUpdate(); float offsetHeight = 0; pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false); pos.Z += offsetHeight; group.AbsolutePosition = pos; // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight); } else { group.SetFromItemID(itemID); } SceneObjectPart rootPart = null; try { rootPart = group.GetChildPart(group.UUID); } catch (NullReferenceException) { string isAttachment = ""; if (attachment) { isAttachment = " Object was an attachment"; } m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); } // Since renaming the item in the inventory does not affect the name stored // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. rootPart.Name = item.Name; rootPart.Description = item.Description; List <SceneObjectPart> partList = new List <SceneObjectPart>(group.Children.Values); group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if (rootPart.OwnerID != item.Owner) { //Need to kill the for sale here rootPart.ObjectSaleType = 0; rootPart.SalePrice = 10; if (m_Scene.Permissions.PropagatePermissions()) { if ((item.CurrentPermissions & 8) != 0) { foreach (SceneObjectPart part in partList) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } group.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in partList) { if (part.OwnerID != item.Owner) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); } else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam! { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } rootPart.TrimPermissions(); if (!attachment) { if (group.RootPart.Shape.PCode == (byte)PCode.Prim) { group.ClearPartAttachmentData(); } // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0); rootPart.ParentGroup.ResumeScripts(); rootPart.ScheduleFullUpdate(); } if (!m_Scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { // If this is done on attachments, no // copy ones will be lost, so avoid it // if (!attachment) { List <UUID> uuids = new List <UUID>(); uuids.Add(item.ID); m_Scene.InventoryService.DeleteItems(item.Owner, uuids); } } } return(rootPart.ParentGroup); } } return(null); }
/// <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; } }
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); }
/// <summary> /// Rez an object into the scene from the user's inventory /// </summary> /// <remarks> /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing /// things to the scene. The caller should be doing that, I think. /// </remarks> /// <param name="remoteClient"></param> /// <param name="itemID"></param> /// <param name="RayEnd"></param> /// <param name="RayStart"></param> /// <param name="RayTargetID"></param> /// <param name="BypassRayCast"></param> /// <param name="RayEndIsIntersection"></param> /// <param name="RezSelected"></param> /// <param name="RemoveItem"></param> /// <param name="fromTaskID"></param> /// <param name="attachment"></param> /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns> public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { // m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); Vector3 pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, scale, false); // Rez object InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_Scene.InventoryService.GetItem(item); if (item != null) { item.Owner = remoteClient.AgentId; AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); SceneObjectGroup group = null; if (rezAsset != null) { UUID itemId = UUID.Zero; // If we have permission to copy then link the rezzed object back to the user inventory // item that it came from. This allows us to enable 'save object to inventory' if (!m_Scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { itemId = item.ID; } } else { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { // Brave new fullperm world itemId = item.ID; } } string xmlData = Utils.BytesToString(rezAsset.Data); List <SceneObjectGroup> objlist = new List <SceneObjectGroup>(); List <Vector3> veclist = new List <Vector3>(); XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlData); XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); if (e == null || attachment) // Single { SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat( itemId, xmlData); objlist.Add(g); veclist.Add(new Vector3(0, 0, 0)); float offsetHeight = 0; pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); pos.Z += offsetHeight; } else { XmlElement coll = (XmlElement)e; float bx = Convert.ToSingle(coll.GetAttribute("x")); float by = Convert.ToSingle(coll.GetAttribute("y")); float bz = Convert.ToSingle(coll.GetAttribute("z")); Vector3 bbox = new Vector3(bx, by, bz); pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, bbox, false); pos -= bbox / 2; XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); foreach (XmlNode n in groups) { SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat( itemId, n.OuterXml); objlist.Add(g); XmlElement el = (XmlElement)n; string rawX = el.GetAttribute("offsetx"); string rawY = el.GetAttribute("offsety"); string rawZ = el.GetAttribute("offsetz"); // // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", // g.Name, rawX, rawY, rawZ); float x = Convert.ToSingle(rawX); float y = Convert.ToSingle(rawY); float z = Convert.ToSingle(rawZ); veclist.Add(new Vector3(x, y, z)); } } int primcount = 0; foreach (SceneObjectGroup g in objlist) { primcount += g.PrimCount; } if (!m_Scene.Permissions.CanRezObject( primcount, remoteClient.AgentId, pos) && !attachment) { // The client operates in no fail mode. It will // have already removed the item from the folder // if it's no copy. // Put it back if it's not an attachment // if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) { remoteClient.SendBulkUpdateInventory(item); } return(null); } for (int i = 0; i < objlist.Count; i++) { group = objlist[i]; Vector3 storedPosition = group.AbsolutePosition; if (group.UUID == UUID.Zero) { m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); } group.RootPart.FromFolderID = item.Folder; // If it's rezzed in world, select it. Much easier to // find small items. // if (!attachment) { group.RootPart.CreateSelected = true; foreach (SceneObjectPart child in group.Parts) { child.CreateSelected = true; } } group.ResetIDs(); if (attachment) { group.RootPart.Flags |= PrimFlags.Phantom; group.RootPart.IsAttachment = true; } // If we're rezzing an attachment then don't ask // AddNewSceneObject() to update the client since // we'll be doing that later on. Scheduling more than // one full update during the attachment // process causes some clients to fail to display the // attachment properly. m_Scene.AddNewSceneObject(group, true, false); // if attachment we set it's asset id so object updates // can reflect that, if not, we set it's position in world. if (!attachment) { group.ScheduleGroupForFullUpdate(); group.AbsolutePosition = pos + veclist[i]; } else { group.SetFromItemID(itemID); } SceneObjectPart rootPart = null; try { rootPart = group.GetChildPart(group.UUID); } catch (NullReferenceException) { string isAttachment = ""; if (attachment) { isAttachment = " Object was an attachment"; } m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); } // Since renaming the item in the inventory does not // affect the name stored in the serialization, transfer // the correct name from the inventory to the // object itself before we rez. // // Only do these for the first object if we are rezzing a coalescence. if (i == 0) { rootPart.Name = item.Name; rootPart.Description = item.Description; rootPart.ObjectSaleType = item.SaleType; rootPart.SalePrice = item.SalePrice; } group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { //Need to kill the for sale here rootPart.ObjectSaleType = 0; rootPart.SalePrice = 10; if (m_Scene.Permissions.PropagatePermissions()) { foreach (SceneObjectPart part in group.Parts) { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; } part.GroupMask = 0; // DO NOT propagate here } group.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in group.Parts) { if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); part.GroupMask = 0; // DO NOT propagate here } part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; } rootPart.TrimPermissions(); if (!attachment) { if (group.RootPart.Shape.PCode == (byte)PCode.Prim) { group.ClearPartAttachmentData(); } // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); rootPart.ParentGroup.ResumeScripts(); rootPart.ScheduleFullUpdate(); } } if (!m_Scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { // If this is done on attachments, no // copy ones will be lost, so avoid it // if (!attachment) { List <UUID> uuids = new List <UUID>(); uuids.Add(item.ID); m_Scene.InventoryService.DeleteItems(item.Owner, uuids); } } } } return(group); } return(null); }
public virtual SceneObjectGroup RezObject( IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); if (rezAsset == null) { if (item != null) { m_log.WarnFormat( "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", assetID, item.Name, item.ID, remoteClient.Name); } else { m_log.WarnFormat( "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()", assetID, remoteClient.Name); } return(null); } SceneObjectGroup group = null; string xmlData = Utils.BytesToString(rezAsset.Data); List <SceneObjectGroup> objlist = new List <SceneObjectGroup>(); List <Vector3> veclist = new List <Vector3>(); byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); Vector3 pos; XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlData); XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); if (e == null || attachment) // Single { SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); objlist.Add(g); veclist.Add(Vector3.Zero); float offsetHeight = 0; pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); pos.Z += offsetHeight; } else { XmlElement coll = (XmlElement)e; float bx = Convert.ToSingle(coll.GetAttribute("x")); float by = Convert.ToSingle(coll.GetAttribute("y")); float bz = Convert.ToSingle(coll.GetAttribute("z")); Vector3 bbox = new Vector3(bx, by, bz); pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, bbox, false); pos -= bbox / 2; XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); foreach (XmlNode n in groups) { SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); objlist.Add(g); XmlElement el = (XmlElement)n; string rawX = el.GetAttribute("offsetx"); string rawY = el.GetAttribute("offsety"); string rawZ = el.GetAttribute("offsetz"); // // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", // g.Name, rawX, rawY, rawZ); float x = Convert.ToSingle(rawX); float y = Convert.ToSingle(rawY); float z = Convert.ToSingle(rawZ); veclist.Add(new Vector3(x, y, z)); } } if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) { return(null); } for (int i = 0; i < objlist.Count; i++) { group = objlist[i]; // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); // Vector3 storedPosition = group.AbsolutePosition; if (group.UUID == UUID.Zero) { m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); } // if this was previously an attachment and is now being rezzed, // save the old attachment info. if (group.IsAttachment == false && group.RootPart.Shape.State != 0) { group.RootPart.AttachedPos = group.AbsolutePosition; group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; } foreach (SceneObjectPart part in group.Parts) { // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. part.LastOwnerID = part.OwnerID; part.OwnerID = remoteClient.AgentId; } if (!attachment) { // If it's rezzed in world, select it. Much easier to // find small items. // foreach (SceneObjectPart part in group.Parts) { part.CreateSelected = true; } } group.ResetIDs(); if (attachment) { group.RootPart.Flags |= PrimFlags.Phantom; group.IsAttachment = true; } // If we're rezzing an attachment then don't ask // AddNewSceneObject() to update the client since // we'll be doing that later on. Scheduling more than // one full update during the attachment // process causes some clients to fail to display the // attachment properly. m_Scene.AddNewSceneObject(group, true, false); // if attachment we set it's asset id so object updates // can reflect that, if not, we set it's position in world. if (!attachment) { group.ScheduleGroupForFullUpdate(); group.AbsolutePosition = pos + veclist[i]; } group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if (!attachment) { SceneObjectPart rootPart = group.RootPart; if (rootPart.Shape.PCode == (byte)PCode.Prim) { group.ClearPartAttachmentData(); } // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); rootPart.ParentGroup.ResumeScripts(); rootPart.ScheduleFullUpdate(); } // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); } if (item != null) { DoPostRezWhenFromItem(item, attachment); } return(group); }