OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
XInventoryService.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.Collections.Generic;
30 using OpenMetaverse;
31 using log4net;
32 using Nini.Config;
33 using System.Reflection;
34 using OpenSim.Services.Base;
35 using OpenSim.Services.Interfaces;
36 using OpenSim.Data;
37 using OpenSim.Framework;
38 
39 namespace OpenSim.Services.InventoryService
40 {
42  {
43  private static readonly ILog m_log =
44  LogManager.GetLogger(
45  MethodBase.GetCurrentMethod().DeclaringType);
46 
48  protected bool m_AllowDelete = true;
49  protected string m_ConfigName = "InventoryService";
50 
51  public XInventoryService(IConfigSource config)
52  : this(config, "InventoryService")
53  {
54  }
55 
56  public XInventoryService(IConfigSource config, string configName) : base(config)
57  {
58  if (configName != string.Empty)
59  m_ConfigName = configName;
60 
61  string dllName = String.Empty;
62  string connString = String.Empty;
63  //string realm = "Inventory"; // OSG version doesn't use this
64 
65  //
66  // Try reading the [InventoryService] section first, if it exists
67  //
68  IConfig authConfig = config.Configs[m_ConfigName];
69  if (authConfig != null)
70  {
71  dllName = authConfig.GetString("StorageProvider", dllName);
72  connString = authConfig.GetString("ConnectionString", connString);
73  m_AllowDelete = authConfig.GetBoolean("AllowDelete", true);
74  // realm = authConfig.GetString("Realm", realm);
75  }
76 
77  //
78  // Try reading the [DatabaseService] section, if it exists
79  //
80  IConfig dbConfig = config.Configs["DatabaseService"];
81  if (dbConfig != null)
82  {
83  if (dllName == String.Empty)
84  dllName = dbConfig.GetString("StorageProvider", String.Empty);
85  if (connString == String.Empty)
86  connString = dbConfig.GetString("ConnectionString", String.Empty);
87  }
88 
89  //
90  // We tried, but this doesn't exist. We can't proceed.
91  //
92  if (dllName == String.Empty)
93  throw new Exception("No StorageProvider configured");
94 
95  m_Database = LoadPlugin<IXInventoryData>(dllName,
96  new Object[] {connString, String.Empty});
97 
98  if (m_Database == null)
99  throw new Exception("Could not find a storage interface in the given module");
100  }
101 
102  public virtual bool CreateUserInventory(UUID principalID)
103  {
104  // This is braindeaad. We can't ever communicate that we fixed
105  // an existing inventory. Well, just return root folder status,
106  // but check sanity anyway.
107  //
108  bool result = false;
109 
110  InventoryFolderBase rootFolder = GetRootFolder(principalID);
111 
112  if (rootFolder == null)
113  {
114  rootFolder = ConvertToOpenSim(CreateFolder(principalID, UUID.Zero, (int)FolderType.Root, InventoryFolderBase.ROOT_FOLDER_NAME));
115  result = true;
116  }
117 
118  XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootFolder.ID);
119 
120  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Animation) return true; return false; }))
121  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Animation, "Animations");
122  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.BodyPart) return true; return false; }))
123  CreateFolder(principalID, rootFolder.ID, (int)FolderType.BodyPart, "Body Parts");
124  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.CallingCard) return true; return false; }))
125  {
126  XInventoryFolder folder = CreateFolder(principalID, rootFolder.ID, (int)FolderType.CallingCard, "Calling Cards");
127  folder = CreateFolder(principalID, folder.folderID, (int)FolderType.CallingCard, "Friends");
128  CreateFolder(principalID, folder.folderID, (int)FolderType.CallingCard, "All");
129  }
130  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Clothing) return true; return false; }))
131  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Clothing, "Clothing");
132  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.CurrentOutfit) return true; return false; }))
133  CreateFolder(principalID, rootFolder.ID, (int)FolderType.CurrentOutfit, "Current Outfit");
134  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Favorites) return true; return false; }))
135  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Favorites, "Favorites");
136  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Gesture) return true; return false; }))
137  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Gesture, "Gestures");
138  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Landmark) return true; return false; }))
139  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Landmark, "Landmarks");
140  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.LostAndFound) return true; return false; }))
141  CreateFolder(principalID, rootFolder.ID, (int)FolderType.LostAndFound, "Lost And Found");
142  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Notecard) return true; return false; }))
143  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Notecard, "Notecards");
144  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Object) return true; return false; }))
145  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Object, "Objects");
146  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Snapshot) return true; return false; }))
147  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Snapshot, "Photo Album");
148  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.LSLText) return true; return false; }))
149  CreateFolder(principalID, rootFolder.ID, (int)FolderType.LSLText, "Scripts");
150  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Sound) return true; return false; }))
151  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Sound, "Sounds");
152  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Texture) return true; return false; }))
153  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Texture, "Textures");
154  if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Trash) return true; return false; }))
155  CreateFolder(principalID, rootFolder.ID, (int)FolderType.Trash, "Trash");
156 
157  return result;
158  }
159 
160  protected XInventoryFolder CreateFolder(UUID principalID, UUID parentID, int type, string name)
161  {
162  XInventoryFolder newFolder = new XInventoryFolder();
163 
164  newFolder.folderName = name;
165  newFolder.type = type;
166  newFolder.version = 1;
167  newFolder.folderID = UUID.Random();
168  newFolder.agentID = principalID;
169  newFolder.parentFolderID = parentID;
170 
171  m_Database.StoreFolder(newFolder);
172 
173  return newFolder;
174  }
175 
176  protected virtual XInventoryFolder[] GetSystemFolders(UUID principalID, UUID rootID)
177  {
178 // m_log.DebugFormat("[XINVENTORY SERVICE]: Getting system folders for {0}", principalID);
179 
180  XInventoryFolder[] allFolders = m_Database.GetFolders(
181  new string[] { "agentID", "parentFolderID" },
182  new string[] { principalID.ToString(), rootID.ToString() });
183 
184  XInventoryFolder[] sysFolders = Array.FindAll(
185  allFolders,
186  delegate (XInventoryFolder f)
187  {
188  if (f.type > 0)
189  return true;
190  return false;
191  });
192 
193 // m_log.DebugFormat(
194 // "[XINVENTORY SERVICE]: Found {0} system folders for {1}", sysFolders.Length, principalID);
195 
196  return sysFolders;
197  }
198 
199  public virtual List<InventoryFolderBase> GetInventorySkeleton(UUID principalID)
200  {
201  XInventoryFolder[] allFolders = m_Database.GetFolders(
202  new string[] { "agentID" },
203  new string[] { principalID.ToString() });
204 
205  if (allFolders.Length == 0)
206  return null;
207 
208  List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
209 
210  foreach (XInventoryFolder x in allFolders)
211  {
212  //m_log.DebugFormat("[XINVENTORY SERVICE]: Adding folder {0} to skeleton", x.folderName);
213  folders.Add(ConvertToOpenSim(x));
214  }
215 
216  return folders;
217  }
218 
219  public virtual InventoryFolderBase GetRootFolder(UUID principalID)
220  {
221  XInventoryFolder[] folders = m_Database.GetFolders(
222  new string[] { "agentID", "parentFolderID"},
223  new string[] { principalID.ToString(), UUID.Zero.ToString() });
224 
225  if (folders.Length == 0)
226  return null;
227 
228  XInventoryFolder root = null;
229  foreach (XInventoryFolder folder in folders)
230  {
232  {
233  root = folder;
234  break;
235  }
236  }
237 
238  if (root == null) // oops
239  root = folders[0];
240 
241  return ConvertToOpenSim(root);
242  }
243 
244  public virtual InventoryFolderBase GetFolderForType(UUID principalID, FolderType type)
245  {
246 // m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID);
247 
248  InventoryFolderBase rootFolder = GetRootFolder(principalID);
249 
250  if (rootFolder == null)
251  {
252  m_log.WarnFormat(
253  "[XINVENTORY]: Found no root folder for {0} in GetFolderForType() when looking for {1}",
254  principalID, type);
255 
256  return null;
257  }
258 
259  return GetSystemFolderForType(rootFolder, type);
260  }
261 
262  private InventoryFolderBase GetSystemFolderForType(InventoryFolderBase rootFolder, FolderType type)
263  {
264  //m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0}", type);
265 
266  if (type == FolderType.Root)
267  return rootFolder;
268 
269  XInventoryFolder[] folders = m_Database.GetFolders(
270  new string[] { "agentID", "parentFolderID", "type"},
271  new string[] { rootFolder.Owner.ToString(), rootFolder.ID.ToString(), ((int)type).ToString() });
272 
273  if (folders.Length == 0)
274  {
275  //m_log.WarnFormat("[XINVENTORY SERVICE]: Found no folder for type {0} ", type);
276  return null;
277  }
278 
279  //m_log.DebugFormat(
280  // "[XINVENTORY SERVICE]: Found folder {0} {1} for type {2}",
281  // folders[0].folderName, folders[0].folderID, type);
282 
283  return ConvertToOpenSim(folders[0]);
284  }
285 
286  public virtual InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
287  {
288  // This method doesn't receive a valud principal id from the
289  // connector. So we disregard the principal and look
290  // by ID.
291  //
292  //m_log.DebugFormat("[XINVENTORY SERVICE]: Fetch contents for folder {0}", folderID.ToString());
293  InventoryCollection inventory = new InventoryCollection();
294  inventory.OwnerID = principalID;
295  inventory.Folders = new List<InventoryFolderBase>();
296  inventory.Items = new List<InventoryItemBase>();
297 
298  XInventoryFolder[] folders = m_Database.GetFolders(
299  new string[] { "parentFolderID"},
300  new string[] { folderID.ToString() });
301 
302  foreach (XInventoryFolder x in folders)
303  {
304  //m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to response", x.folderName);
305  inventory.Folders.Add(ConvertToOpenSim(x));
306  }
307 
308  XInventoryItem[] items = m_Database.GetItems(
309  new string[] { "parentFolderID"},
310  new string[] { folderID.ToString() });
311 
312  foreach (XInventoryItem i in items)
313  {
314  //m_log.DebugFormat("[XINVENTORY]: Adding item {0} to response", i.inventoryName);
315  inventory.Items.Add(ConvertToOpenSim(i));
316  }
317 
318  InventoryFolderBase f = new InventoryFolderBase(folderID, principalID);
319  f = GetFolder(f);
320  if (f != null)
321  {
322  inventory.Version = f.Version;
323  inventory.OwnerID = f.Owner;
324  }
325  inventory.FolderID = folderID;
326 
327  return inventory;
328  }
329 
330  public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
331  {
332  InventoryCollection[] multiple = new InventoryCollection[folderIDs.Length];
333  int i = 0;
334  foreach (UUID fid in folderIDs)
335  multiple[i++] = GetFolderContent(principalID, fid);
336 
337  return multiple;
338  }
339 
340  public virtual List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
341  {
342 // m_log.DebugFormat("[XINVENTORY]: Fetch items for folder {0}", folderID);
343 
344  // Since we probably don't get a valid principal here, either ...
345  //
346  List<InventoryItemBase> invItems = new List<InventoryItemBase>();
347 
348  XInventoryItem[] items = m_Database.GetItems(
349  new string[] { "parentFolderID" },
350  new string[] { folderID.ToString() });
351 
352  foreach (XInventoryItem i in items)
353  invItems.Add(ConvertToOpenSim(i));
354 
355  return invItems;
356  }
357 
358  public virtual bool AddFolder(InventoryFolderBase folder)
359  {
360 // m_log.DebugFormat("[XINVENTORY]: Add folder {0} type {1} in parent {2}", folder.Name, folder.Type, folder.ParentID);
361 
362  InventoryFolderBase check = GetFolder(folder);
363  if (check != null)
364  return false;
365 
366  if (folder.Type != (short)FolderType.None)
367  {
368  InventoryFolderBase rootFolder = GetRootFolder(folder.Owner);
369 
370  if (rootFolder == null)
371  {
372  m_log.WarnFormat(
373  "[XINVENTORY]: Found no root folder for {0} in AddFolder() when looking for {1}",
374  folder.Owner, folder.Type);
375 
376  return false;
377  }
378 
379  // Check we're not trying to add this as a system folder.
380  if (folder.ParentID == rootFolder.ID)
381  {
382  InventoryFolderBase existingSystemFolder
383  = GetSystemFolderForType(rootFolder, (FolderType)folder.Type);
384 
385  if (existingSystemFolder != null)
386  {
387  m_log.WarnFormat(
388  "[XINVENTORY]: System folder of type {0} already exists when tried to add {1} to {2} for {3}",
389  folder.Type, folder.Name, folder.ParentID, folder.Owner);
390 
391  return false;
392  }
393  }
394  }
395 
396  XInventoryFolder xFolder = ConvertFromOpenSim(folder);
397  return m_Database.StoreFolder(xFolder);
398  }
399 
400  public virtual bool UpdateFolder(InventoryFolderBase folder)
401  {
402 // m_log.DebugFormat("[XINVENTORY]: Update folder {0} {1} ({2})", folder.Name, folder.Type, folder.ID);
403 
404  XInventoryFolder xFolder = ConvertFromOpenSim(folder);
405  InventoryFolderBase check = GetFolder(folder);
406 
407  if (check == null)
408  return AddFolder(folder);
409 
410  if ((check.Type != (short)FolderType.None || xFolder.type != (short)FolderType.None)
411  && (check.Type != (short)FolderType.Outfit || xFolder.type != (short)FolderType.Outfit))
412  {
413  if (xFolder.version < check.Version)
414  {
415 // m_log.DebugFormat("[XINVENTORY]: {0} < {1} can't do", xFolder.version, check.Version);
416  return false;
417  }
418 
419  check.Version = (ushort)xFolder.version;
420  xFolder = ConvertFromOpenSim(check);
421 
422 // m_log.DebugFormat(
423 // "[XINVENTORY]: Storing version only update to system folder {0} {1} {2}",
424 // xFolder.folderName, xFolder.version, xFolder.type);
425 
426  return m_Database.StoreFolder(xFolder);
427  }
428 
429  if (xFolder.version < check.Version)
430  xFolder.version = check.Version;
431 
432  xFolder.folderID = check.ID;
433 
434  return m_Database.StoreFolder(xFolder);
435  }
436 
437  public virtual bool MoveFolder(InventoryFolderBase folder)
438  {
439  return m_Database.MoveFolder(folder.ID.ToString(), folder.ParentID.ToString());
440  }
441 
442  // We don't check the principal's ID here
443  //
444  public virtual bool DeleteFolders(UUID principalID, List<UUID> folderIDs)
445  {
446  return DeleteFolders(principalID, folderIDs, true);
447  }
448 
449  public virtual bool DeleteFolders(UUID principalID, List<UUID> folderIDs, bool onlyIfTrash)
450  {
451  if (!m_AllowDelete)
452  return false;
453 
454  // Ignore principal ID, it's bogus at connector level
455  //
456  foreach (UUID id in folderIDs)
457  {
458  if (onlyIfTrash && !ParentIsTrash(id))
459  continue;
460  //m_log.InfoFormat("[XINVENTORY SERVICE]: Delete folder {0}", id);
462  f.ID = id;
463  PurgeFolder(f, onlyIfTrash);
464  m_Database.DeleteFolders("folderID", id.ToString());
465  }
466 
467  return true;
468  }
469 
470  public virtual bool PurgeFolder(InventoryFolderBase folder)
471  {
472  return PurgeFolder(folder, true);
473  }
474 
475  public virtual bool PurgeFolder(InventoryFolderBase folder, bool onlyIfTrash)
476  {
477  if (!m_AllowDelete)
478  return false;
479 
480  if (onlyIfTrash && !ParentIsTrash(folder.ID))
481  return false;
482 
483  XInventoryFolder[] subFolders = m_Database.GetFolders(
484  new string[] { "parentFolderID" },
485  new string[] { folder.ID.ToString() });
486 
487  foreach (XInventoryFolder x in subFolders)
488  {
489  PurgeFolder(ConvertToOpenSim(x), onlyIfTrash);
490  m_Database.DeleteFolders("folderID", x.folderID.ToString());
491  }
492 
493  m_Database.DeleteItems("parentFolderID", folder.ID.ToString());
494 
495  return true;
496  }
497 
498  public virtual bool AddItem(InventoryItemBase item)
499  {
500 // m_log.DebugFormat(
501 // "[XINVENTORY SERVICE]: Adding item {0} {1} to folder {2} for {3}", item.Name, item.ID, item.Folder, item.Owner);
502 
503  return m_Database.StoreItem(ConvertFromOpenSim(item));
504  }
505 
506  public virtual bool UpdateItem(InventoryItemBase item)
507  {
508  if (!m_AllowDelete)
509  if (item.AssetType == (sbyte)AssetType.Link || item.AssetType == (sbyte)AssetType.LinkFolder)
510  return false;
511 
512 // m_log.InfoFormat(
513 // "[XINVENTORY SERVICE]: Updating item {0} {1} in folder {2}", item.Name, item.ID, item.Folder);
514 
515  InventoryItemBase retrievedItem = GetItem(item);
516 
517  if (retrievedItem == null)
518  {
519  m_log.WarnFormat(
520  "[XINVENTORY SERVICE]: Tried to update item {0} {1}, owner {2} but no existing item found.",
521  item.Name, item.ID, item.Owner);
522 
523  return false;
524  }
525 
526  // Do not allow invariants to change. Changes to folder ID occur in MoveItems()
527  if (retrievedItem.InvType != item.InvType
528  || retrievedItem.AssetType != item.AssetType
529  || retrievedItem.Folder != item.Folder
530  || retrievedItem.CreatorIdentification != item.CreatorIdentification
531  || retrievedItem.Owner != item.Owner)
532  {
533  m_log.WarnFormat(
534  "[XINVENTORY SERVICE]: Caller to UpdateItem() for {0} {1} tried to alter property(s) that should be invariant, (InvType, AssetType, Folder, CreatorIdentification, Owner), existing ({2}, {3}, {4}, {5}, {6}), update ({7}, {8}, {9}, {10}, {11})",
535  retrievedItem.Name,
536  retrievedItem.ID,
537  retrievedItem.InvType,
538  retrievedItem.AssetType,
539  retrievedItem.Folder,
540  retrievedItem.CreatorIdentification,
541  retrievedItem.Owner,
542  item.InvType,
543  item.AssetType,
544  item.Folder,
545  item.CreatorIdentification,
546  item.Owner);
547 
548  item.InvType = retrievedItem.InvType;
549  item.AssetType = retrievedItem.AssetType;
550  item.Folder = retrievedItem.Folder;
551  item.CreatorIdentification = retrievedItem.CreatorIdentification;
552  item.Owner = retrievedItem.Owner;
553  }
554 
555  return m_Database.StoreItem(ConvertFromOpenSim(item));
556  }
557 
558  public virtual bool MoveItems(UUID principalID, List<InventoryItemBase> items)
559  {
560  // Principal is b0rked. *sigh*
561  //
562  foreach (InventoryItemBase i in items)
563  {
564  m_Database.MoveItem(i.ID.ToString(), i.Folder.ToString());
565  }
566 
567  return true;
568  }
569 
570  public virtual bool DeleteItems(UUID principalID, List<UUID> itemIDs)
571  {
572  if (!m_AllowDelete)
573  {
574  // We must still allow links and links to folders to be deleted, otherwise they will build up
575  // in the player's inventory until they can no longer log in. Deletions of links due to code bugs or
576  // similar is inconvenient but on a par with accidental movement of items. The original item is never
577  // touched.
578  foreach (UUID id in itemIDs)
579  {
580  if (!m_Database.DeleteItems(
581  new string[] { "inventoryID", "assetType" },
582  new string[] { id.ToString(), ((sbyte)AssetType.Link).ToString() }))
583  {
584  m_Database.DeleteItems(
585  new string[] { "inventoryID", "assetType" },
586  new string[] { id.ToString(), ((sbyte)AssetType.LinkFolder).ToString() });
587  }
588  }
589  }
590  else
591  {
592  // Just use the ID... *facepalms*
593  //
594  foreach (UUID id in itemIDs)
595  m_Database.DeleteItems("inventoryID", id.ToString());
596  }
597 
598  return true;
599  }
600 
602  {
603  XInventoryItem[] items = m_Database.GetItems(
604  new string[] { "inventoryID" },
605  new string[] { item.ID.ToString() });
606 
607  if (items.Length == 0)
608  return null;
609 
610  return ConvertToOpenSim(items[0]);
611  }
612 
613  public virtual InventoryItemBase[] GetMultipleItems(UUID userID, UUID[] ids)
614  {
615  InventoryItemBase[] items = new InventoryItemBase[ids.Length];
616  int i = 0;
618  item.Owner = userID;
619  foreach (UUID id in ids)
620  {
621  item.ID = id;
622  items[i++] = GetItem(item);
623  }
624 
625  return items;
626  }
627 
629  {
630  XInventoryFolder[] folders = m_Database.GetFolders(
631  new string[] { "folderID"},
632  new string[] { folder.ID.ToString() });
633 
634  if (folders.Length == 0)
635  return null;
636 
637  return ConvertToOpenSim(folders[0]);
638  }
639 
640  public virtual List<InventoryItemBase> GetActiveGestures(UUID principalID)
641  {
642  XInventoryItem[] items = m_Database.GetActiveGestures(principalID);
643 
644  if (items.Length == 0)
645  return new List<InventoryItemBase>();
646 
647  List<InventoryItemBase> ret = new List<InventoryItemBase>();
648 
649  foreach (XInventoryItem x in items)
650  ret.Add(ConvertToOpenSim(x));
651 
652  return ret;
653  }
654 
655  public virtual int GetAssetPermissions(UUID principalID, UUID assetID)
656  {
657  return m_Database.GetAssetPermissions(principalID, assetID);
658  }
659 
660  // Unused.
661  //
662  public bool HasInventoryForUser(UUID userID)
663  {
664  return false;
665  }
666 
667  // CM Helpers
668  //
670  {
671  InventoryFolderBase newFolder = new InventoryFolderBase();
672 
673  newFolder.ParentID = folder.parentFolderID;
674  newFolder.Type = (short)folder.type;
676  //if (newFolder.Type == InventoryItemBase.SUITCASE_FOLDER_TYPE)
677  // newFolder.Type = InventoryItemBase.SUITCASE_FOLDER_FAKE_TYPE;
678  newFolder.Version = (ushort)folder.version;
679  newFolder.Name = folder.folderName;
680  newFolder.Owner = folder.agentID;
681  newFolder.ID = folder.folderID;
682 
683  return newFolder;
684  }
685 
687  {
688  XInventoryFolder newFolder = new XInventoryFolder();
689 
690  newFolder.parentFolderID = folder.ParentID;
691  newFolder.type = (int)folder.Type;
692  newFolder.version = (int)folder.Version;
693  newFolder.folderName = folder.Name;
694  newFolder.agentID = folder.Owner;
695  newFolder.folderID = folder.ID;
696 
697  return newFolder;
698  }
699 
701  {
702  InventoryItemBase newItem = new InventoryItemBase();
703 
704  newItem.AssetID = item.assetID;
705  newItem.AssetType = item.assetType;
706  newItem.Name = item.inventoryName;
707  newItem.Owner = item.avatarID;
708  newItem.ID = item.inventoryID;
709  newItem.InvType = item.invType;
710  newItem.Folder = item.parentFolderID;
711  newItem.CreatorIdentification = item.creatorID;
712  newItem.Description = item.inventoryDescription;
713  newItem.NextPermissions = (uint)item.inventoryNextPermissions;
714  newItem.CurrentPermissions = (uint)item.inventoryCurrentPermissions;
715  newItem.BasePermissions = (uint)item.inventoryBasePermissions;
716  newItem.EveryOnePermissions = (uint)item.inventoryEveryOnePermissions;
717  newItem.GroupPermissions = (uint)item.inventoryGroupPermissions;
718  newItem.GroupID = item.groupID;
719  if (item.groupOwned == 0)
720  newItem.GroupOwned = false;
721  else
722  newItem.GroupOwned = true;
723  newItem.SalePrice = item.salePrice;
724  newItem.SaleType = (byte)item.saleType;
725  newItem.Flags = (uint)item.flags;
726  newItem.CreationDate = item.creationDate;
727 
728  return newItem;
729  }
730 
732  {
733  XInventoryItem newItem = new XInventoryItem();
734 
735  newItem.assetID = item.AssetID;
736  newItem.assetType = item.AssetType;
737  newItem.inventoryName = item.Name;
738  newItem.avatarID = item.Owner;
739  newItem.inventoryID = item.ID;
740  newItem.invType = item.InvType;
741  newItem.parentFolderID = item.Folder;
742  newItem.creatorID = item.CreatorIdentification;
743  newItem.inventoryDescription = item.Description;
744  newItem.inventoryNextPermissions = (int)item.NextPermissions;
745  newItem.inventoryCurrentPermissions = (int)item.CurrentPermissions;
746  newItem.inventoryBasePermissions = (int)item.BasePermissions;
747  newItem.inventoryEveryOnePermissions = (int)item.EveryOnePermissions;
748  newItem.inventoryGroupPermissions = (int)item.GroupPermissions;
749  newItem.groupID = item.GroupID;
750  if (item.GroupOwned)
751  newItem.groupOwned = 1;
752  else
753  newItem.groupOwned = 0;
754  newItem.salePrice = item.SalePrice;
755  newItem.saleType = (int)item.SaleType;
756  newItem.flags = (int)item.Flags;
757  newItem.creationDate = item.CreationDate;
758 
759  return newItem;
760  }
761 
762  private bool ParentIsTrash(UUID folderID)
763  {
764  XInventoryFolder[] folder = m_Database.GetFolders(new string[] {"folderID"}, new string[] {folderID.ToString()});
765  if (folder.Length < 1)
766  return false;
767 
768  if (folder[0].type == (int)FolderType.Trash)
769  return true;
770 
771  UUID parentFolder = folder[0].parentFolderID;
772 
773  while (parentFolder != UUID.Zero)
774  {
775  XInventoryFolder[] parent = m_Database.GetFolders(new string[] {"folderID"}, new string[] {parentFolder.ToString()});
776  if (parent.Length < 1)
777  return false;
778 
779  if (parent[0].type == (int)FolderType.Trash)
780  return true;
781  if (parent[0].type == (int)FolderType.Root)
782  return false;
783 
784  parentFolder = parent[0].parentFolderID;
785  }
786  return false;
787  }
788  }
789 }
virtual XInventoryFolder[] GetSystemFolders(UUID principalID, UUID rootID)
virtual bool AddItem(InventoryItemBase item)
Add a new item to the user's inventory
virtual InventoryFolderBase GetFolder(InventoryFolderBase folder)
Get a folder, given by its UUID
virtual bool AddFolder(InventoryFolderBase folder)
Add a new folder to the user's inventory
InventoryFolderBase ConvertToOpenSim(XInventoryFolder folder)
virtual bool UpdateItem(InventoryItemBase item)
Update an item in the user's inventory
virtual bool MoveItems(UUID principalID, List< InventoryItemBase > items)
bool HasInventoryForUser(UUID userID)
Does the given user have an inventory structure?
virtual List< InventoryFolderBase > GetInventorySkeleton(UUID principalID)
Gets the skeleton of the inventory – folders only
XInventoryFolder CreateFolder(UUID principalID, UUID parentID, int type, string name)
virtual UUID Owner
The agent who's inventory this is contained by
virtual bool UpdateFolder(InventoryFolderBase folder)
Update a folder in the user's inventory
virtual InventoryFolderBase GetRootFolder(UUID principalID)
Retrieve the root inventory folder for the given user.
virtual InventoryItemBase[] GetMultipleItems(UUID userID, UUID[] ids)
Get multiple items, given by their UUIDs
virtual bool MoveFolder(InventoryFolderBase folder)
Move an inventory folder to a new location
virtual bool DeleteFolders(UUID principalID, List< UUID > folderIDs, bool onlyIfTrash)
virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
Gets everything (folders and items) inside a folder
virtual List< InventoryItemBase > GetActiveGestures(UUID principalID)
Get the active gestures of the agent.
Inventory Item - contains all the properties associated with an individual inventory piece...
virtual InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
Gets everything (folders and items) inside a folder
virtual bool CreateUserInventory(UUID principalID)
Create the entire inventory for a given user
XInventoryFolder ConvertFromOpenSim(InventoryFolderBase folder)
virtual int GetAssetPermissions(UUID principalID, UUID assetID)
Get the union of permissions of all inventory items that hold the given assetID.
UUID ID
A UUID containing the ID for the inventory node itself
XInventoryItem ConvertFromOpenSim(InventoryItemBase item)
virtual bool DeleteItems(UUID principalID, List< UUID > itemIDs)
Delete an item from the user's inventory
virtual InventoryItemBase GetItem(InventoryItemBase item)
Get an item, given by its UUID
XInventoryService(IConfigSource config, string configName)
virtual bool PurgeFolder(InventoryFolderBase folder)
Purge an inventory folder of all its items and subfolders.
virtual List< InventoryItemBase > GetFolderItems(UUID principalID, UUID folderID)
Gets the items inside a folder
InventoryItemBase ConvertToOpenSim(XInventoryItem item)
virtual InventoryFolderBase GetFolderForType(UUID principalID, FolderType type)
Gets the user folder for the given folder-type
virtual bool PurgeFolder(InventoryFolderBase folder, bool onlyIfTrash)
Used to serialize a whole inventory for transfer over the network.
virtual bool DeleteFolders(UUID principalID, List< UUID > folderIDs)
Delete an item from the user's inventory
string CreatorIdentification
Used by the DB layer to retrieve / store the entire user identification. The identification can eithe...