diff options
Diffstat (limited to 'OpenSim/Services/InventoryService/XInventoryService.cs')
-rw-r--r-- | OpenSim/Services/InventoryService/XInventoryService.cs | 789 |
1 files changed, 789 insertions, 0 deletions
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs new file mode 100644 index 0000000..b75193f --- /dev/null +++ b/OpenSim/Services/InventoryService/XInventoryService.cs | |||
@@ -0,0 +1,789 @@ | |||
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 | { | ||
41 | public class XInventoryService : ServiceBase, IInventoryService | ||
42 | { | ||
43 | private static readonly ILog m_log = | ||
44 | LogManager.GetLogger( | ||
45 | MethodBase.GetCurrentMethod().DeclaringType); | ||
46 | |||
47 | protected IXInventoryData m_Database; | ||
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 | { | ||
231 | if (folder.folderName == InventoryFolderBase.ROOT_FOLDER_NAME) | ||
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); | ||
461 | InventoryFolderBase f = new InventoryFolderBase(); | ||
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 | |||
601 | public virtual InventoryItemBase GetItem(InventoryItemBase item) | ||
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; | ||
617 | InventoryItemBase item = new InventoryItemBase(); | ||
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 | |||
628 | public virtual InventoryFolderBase GetFolder(InventoryFolderBase folder) | ||
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 | // | ||
669 | protected InventoryFolderBase ConvertToOpenSim(XInventoryFolder folder) | ||
670 | { | ||
671 | InventoryFolderBase newFolder = new InventoryFolderBase(); | ||
672 | |||
673 | newFolder.ParentID = folder.parentFolderID; | ||
674 | newFolder.Type = (short)folder.type; | ||
675 | //// Viewer can't understand anything that's not in it's LLFolderType enum | ||
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 | |||
686 | protected XInventoryFolder ConvertFromOpenSim(InventoryFolderBase folder) | ||
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 | |||
700 | protected InventoryItemBase ConvertToOpenSim(XInventoryItem item) | ||
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 | |||
731 | protected XInventoryItem ConvertFromOpenSim(InventoryItemBase item) | ||
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 | } | ||