OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
SceneObjectGroup.Inventory.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.IO;
30 using System.Reflection;
31 using OpenMetaverse;
32 using log4net;
33 using OpenSim.Framework;
34 using OpenSim.Region.Framework.Interfaces;
35 using System.Collections.Generic;
36 using System.Xml;
38 
39 namespace OpenSim.Region.Framework.Scenes
40 {
41  public partial class SceneObjectGroup : EntityBase
42  {
43  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 
49  {
50  SceneObjectPart[] parts = m_parts.GetArray();
51  for (int i = 0; i < parts.Length; i++)
52  parts[i].Inventory.ForceInventoryPersistence();
53  }
54 
66  public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
67  {
68  int scriptsStarted = 0;
69 
70  if (m_scene == null)
71  {
72  m_log.DebugFormat("[PRIM INVENTORY]: m_scene is null. Unable to create script instances");
73  return 0;
74  }
75 
76  // Don't start scripts if they're turned off in the region!
77  if (!m_scene.RegionInfo.RegionSettings.DisableScripts)
78  {
79  SceneObjectPart[] parts = m_parts.GetArray();
80  for (int i = 0; i < parts.Length; i++)
81  scriptsStarted
82  += parts[i].Inventory.CreateScriptInstances(startParam, postOnRez, engine, stateSource);
83  }
84 
85  return scriptsStarted;
86  }
87 
91  public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
92  {
93  SceneObjectPart[] parts = m_parts.GetArray();
94  for (int i = 0; i < parts.Length; i++)
95  parts[i].Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
96  }
97 
101  public void StopScriptInstances()
102  {
103  Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => p.Inventory.StopScriptInstances());
104  }
105 
114  public bool AddInventoryItem(UUID agentID, uint localID, InventoryItemBase item, UUID copyItemID)
115  {
116 // m_log.DebugFormat(
117 // "[PRIM INVENTORY]: Adding inventory item {0} from {1} to part with local ID {2}",
118 // item.Name, remoteClient.Name, localID);
119 
120  UUID newItemId = (copyItemID != UUID.Zero) ? copyItemID : item.ID;
121 
122  SceneObjectPart part = GetPart(localID);
123  if (part != null)
124  {
125  TaskInventoryItem taskItem = new TaskInventoryItem();
126 
127  taskItem.ItemID = newItemId;
128  taskItem.AssetID = item.AssetID;
129  taskItem.Name = item.Name;
130  taskItem.Description = item.Description;
131  taskItem.OwnerID = part.OwnerID; // Transfer ownership
132  taskItem.CreatorID = item.CreatorIdAsUuid;
133  taskItem.Type = item.AssetType;
134  taskItem.InvType = item.InvType;
135 
136  if (agentID != part.OwnerID && m_scene.Permissions.PropagatePermissions())
137  {
138  taskItem.BasePermissions = item.BasePermissions &
139  item.NextPermissions;
140  taskItem.CurrentPermissions = item.CurrentPermissions &
141  item.NextPermissions;
142  taskItem.EveryonePermissions = item.EveryOnePermissions &
143  item.NextPermissions;
144  taskItem.GroupPermissions = item.GroupPermissions &
145  item.NextPermissions;
146  taskItem.NextPermissions = item.NextPermissions;
147  // We're adding this to a prim we don't own. Force
148  // owner change
149  taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
150  }
151  else
152  {
153  taskItem.BasePermissions = item.BasePermissions;
154  taskItem.CurrentPermissions = item.CurrentPermissions;
155  taskItem.EveryonePermissions = item.EveryOnePermissions;
156  taskItem.GroupPermissions = item.GroupPermissions;
157  taskItem.NextPermissions = item.NextPermissions;
158  }
159 
160  taskItem.Flags = item.Flags;
161 
162 // m_log.DebugFormat(
163 // "[PRIM INVENTORY]: Flags are 0x{0:X} for item {1} added to part {2} by {3}",
164 // taskItem.Flags, taskItem.Name, localID, remoteClient.Name);
165 
166  // TODO: These are pending addition of those fields to TaskInventoryItem
167 // taskItem.SalePrice = item.SalePrice;
168 // taskItem.SaleType = item.SaleType;
169  taskItem.CreationDate = (uint)item.CreationDate;
170 
171  bool addFromAllowedDrop = agentID != part.OwnerID;
172 
173  part.Inventory.AddInventoryItem(taskItem, addFromAllowedDrop);
174 
175  return true;
176  }
177  else
178  {
179  m_log.ErrorFormat(
180  "[PRIM INVENTORY]: " +
181  "Couldn't find prim local ID {0} in group {1}, {2} to add inventory item ID {3}",
182  localID, Name, UUID, newItemId);
183  }
184 
185  return false;
186  }
187 
194  public TaskInventoryItem GetInventoryItem(uint primID, UUID itemID)
195  {
196  SceneObjectPart part = GetPart(primID);
197  if (part != null)
198  {
199  return part.Inventory.GetInventoryItem(itemID);
200  }
201  else
202  {
203  m_log.ErrorFormat(
204  "[PRIM INVENTORY]: " +
205  "Couldn't find prim local ID {0} in prim {1}, {2} to get inventory item ID {3}",
206  primID, part.Name, part.UUID, itemID);
207  }
208 
209  return null;
210  }
211 
219  {
220  SceneObjectPart part = GetPart(item.ParentPartID);
221  if (part != null)
222  {
223  part.Inventory.UpdateInventoryItem(item);
224 
225  return true;
226  }
227  else
228  {
229  m_log.ErrorFormat(
230  "[PRIM INVENTORY]: " +
231  "Couldn't find prim ID {0} to update item {1}, {2}",
232  item.ParentPartID, item.Name, item.ItemID);
233  }
234 
235  return false;
236  }
237 
238  public int RemoveInventoryItem(uint localID, UUID itemID)
239  {
240  SceneObjectPart part = GetPart(localID);
241  if (part != null)
242  {
243  int type = part.Inventory.RemoveInventoryItem(itemID);
244 
245  return type;
246  }
247 
248  return -1;
249  }
250 
252  {
253  return GetEffectivePermissions(false);
254  }
255 
256  public uint GetEffectivePermissions(bool useBase)
257  {
258  uint perms=(uint)(PermissionMask.Modify |
259  PermissionMask.Copy |
260  PermissionMask.Move |
261  PermissionMask.Transfer) | 7;
262 
263  uint ownerMask = 0x7fffffff;
264 
265  SceneObjectPart[] parts = m_parts.GetArray();
266  for (int i = 0; i < parts.Length; i++)
267  {
268  SceneObjectPart part = parts[i];
269 
270  if (useBase)
271  ownerMask &= part.BaseMask;
272  else
273  ownerMask &= part.OwnerMask;
274 
275  perms &= part.Inventory.MaskEffectivePermissions();
276  }
277 
278  if ((ownerMask & (uint)PermissionMask.Modify) == 0)
279  perms &= ~(uint)PermissionMask.Modify;
280  if ((ownerMask & (uint)PermissionMask.Copy) == 0)
281  perms &= ~(uint)PermissionMask.Copy;
282  if ((ownerMask & (uint)PermissionMask.Transfer) == 0)
283  perms &= ~(uint)PermissionMask.Transfer;
284 
285  // If root prim permissions are applied here, this would screw
286  // with in-inventory manipulation of the next owner perms
287  // in a major way. So, let's move this to the give itself.
288  // Yes. I know. Evil.
289 // if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Modify) == 0)
290 // perms &= ~((uint)PermissionMask.Modify >> 13);
291 // if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Copy) == 0)
292 // perms &= ~((uint)PermissionMask.Copy >> 13);
293 // if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Transfer) == 0)
294 // perms &= ~((uint)PermissionMask.Transfer >> 13);
295 
296  return perms;
297  }
298 
300  {
301 // m_log.DebugFormat("[PRIM INVENTORY]: Applying next owner permissions to {0} {1}", Name, UUID);
302 
303  SceneObjectPart[] parts = m_parts.GetArray();
304  for (int i = 0; i < parts.Length; i++)
305  parts[i].ApplyNextOwnerPermissions();
306  }
307 
308  public string GetStateSnapshot()
309  {
310  Dictionary<UUID, string> states = new Dictionary<UUID, string>();
311 
312  SceneObjectPart[] parts = m_parts.GetArray();
313  for (int i = 0; i < parts.Length; i++)
314  {
315  SceneObjectPart part = parts[i];
316  foreach (KeyValuePair<UUID, string> s in part.Inventory.GetScriptStates())
317  states[s.Key] = s.Value;
318  }
319 
320  if (states.Count < 1)
321  return String.Empty;
322 
323  XmlDocument xmldoc = new XmlDocument();
324 
325  XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
326  String.Empty, String.Empty);
327 
328  xmldoc.AppendChild(xmlnode);
329  XmlElement rootElement = xmldoc.CreateElement("", "ScriptData",
330  String.Empty);
331 
332  xmldoc.AppendChild(rootElement);
333 
334 
335  XmlElement wrapper = xmldoc.CreateElement("", "ScriptStates",
336  String.Empty);
337 
338  rootElement.AppendChild(wrapper);
339 
340  foreach (KeyValuePair<UUID, string> state in states)
341  {
342  XmlDocument sdoc = new XmlDocument();
343  sdoc.LoadXml(state.Value);
344  XmlNodeList rootL = sdoc.GetElementsByTagName("State");
345  XmlNode rootNode = rootL[0];
346 
347  XmlNode newNode = xmldoc.ImportNode(rootNode, true);
348  wrapper.AppendChild(newNode);
349  }
350 
351  return xmldoc.InnerXml;
352  }
353 
354  public void SetState(string objXMLData, IScene ins)
355  {
356  if (!(ins is Scene))
357  return;
358 
359  Scene s = (Scene)ins;
360 
361  if (objXMLData == String.Empty)
362  return;
363 
364  IScriptModule scriptModule = null;
365 
366  foreach (IScriptModule sm in s.RequestModuleInterfaces<IScriptModule>())
367  {
368  if (sm.ScriptEngineName == s.DefaultScriptEngine)
369  scriptModule = sm;
370  else if (scriptModule == null)
371  scriptModule = sm;
372  }
373 
374  if (scriptModule == null)
375  return;
376 
377  XmlDocument doc = new XmlDocument();
378  try
379  {
380  doc.LoadXml(objXMLData);
381  }
382  catch (Exception) // (System.Xml.XmlException)
383  {
384  // We will get here if the XML is invalid or in unit
385  // tests. Really should determine which it is and either
386  // fail silently or log it
387  // Fail silently, for now.
388  // TODO: Fix this
389  //
390  return;
391  }
392 
393  XmlNodeList rootL = doc.GetElementsByTagName("ScriptData");
394  if (rootL.Count != 1)
395  return;
396 
397  XmlElement rootE = (XmlElement)rootL[0];
398 
399  XmlNodeList dataL = rootE.GetElementsByTagName("ScriptStates");
400  if (dataL.Count != 1)
401  return;
402 
403  XmlElement dataE = (XmlElement)dataL[0];
404 
405  foreach (XmlNode n in dataE.ChildNodes)
406  {
407  XmlElement stateE = (XmlElement)n;
408  UUID itemID = new UUID(stateE.GetAttribute("UUID"));
409 
410  scriptModule.SetXMLState(itemID, n.OuterXml);
411  }
412  }
413 
414  public void ResumeScripts()
415  {
416  if (m_scene.RegionInfo.RegionSettings.DisableScripts)
417  return;
418 
419  SceneObjectPart[] parts = m_parts.GetArray();
420  for (int i = 0; i < parts.Length; i++)
421  parts[i].Inventory.ResumeScripts();
422  }
423 
428  public bool ContainsScripts()
429  {
430  foreach (SceneObjectPart part in Parts)
431  if (part.Inventory.ContainsScripts())
432  return true;
433 
434  return false;
435  }
436  }
437 }
IEntityInventory Inventory
This part's inventory
bool UpdateInventoryItem(TaskInventoryItem item)
Update an existing inventory item.
bool ContainsScripts()
Returns true if any part in the scene object contains scripts, false otherwise.
int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
Start the scripts contained in all the prims in this group.
bool AddInventoryItem(UUID agentID, uint localID, InventoryItemBase item, UUID copyItemID)
Add an inventory item from a user's inventory to a prim in this scene object.
bool ContainsScripts()
Returns true if this inventory contains any scripts
SceneObjectPart Copy(uint plocalID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed)
Duplicates this part.
void RemoveScriptInstances(bool sceneObjectBeingDeleted)
Stop and remove the scripts contained in all the prims in this group
Represents an item in a task inventory
OpenSim.Framework.PermissionMask PermissionMask
Inventory Item - contains all the properties associated with an individual inventory piece...
TaskInventoryItem GetInventoryItem(uint primID, UUID itemID)
Returns an existing inventory item. Returns the original, so any changes will be live.
UUID ID
A UUID containing the ID for the inventory node itself
void ForceInventoryPersistence()
Force all task inventories of prims in the scene object to persist
void StopScriptInstances()
Stop the scripts contained in all the prims in this group