diff options
Diffstat (limited to 'OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs')
-rw-r--r-- | OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs | 338 |
1 files changed, 218 insertions, 120 deletions
diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs index a999886..cb686e2 100644 --- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | ||
30 | using OpenMetaverse; | 31 | using OpenMetaverse; |
31 | using log4net; | 32 | using log4net; |
32 | using Nini.Config; | 33 | using Nini.Config; |
@@ -58,6 +59,8 @@ namespace OpenSim.Services.HypergridService | |||
58 | 59 | ||
59 | private UserAccountCache m_Cache; | 60 | private UserAccountCache m_Cache; |
60 | 61 | ||
62 | private ExpiringCache<UUID, List<XInventoryFolder>> m_SuitcaseTrees = new ExpiringCache<UUID,List<XInventoryFolder>>(); | ||
63 | |||
61 | public HGSuitcaseInventoryService(IConfigSource config, string configName) | 64 | public HGSuitcaseInventoryService(IConfigSource config, string configName) |
62 | : base(config, configName) | 65 | : base(config, configName) |
63 | { | 66 | { |
@@ -147,16 +150,17 @@ namespace OpenSim.Services.HypergridService | |||
147 | return GetRootFolder(principalID); | 150 | return GetRootFolder(principalID); |
148 | } | 151 | } |
149 | 152 | ||
150 | // | ||
151 | // Use the inherited methods | ||
152 | // | ||
153 | public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID) | 153 | public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID) |
154 | { | 154 | { |
155 | InventoryCollection coll = null; | 155 | InventoryCollection coll = null; |
156 | XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); | ||
156 | XInventoryFolder root = GetRootXFolder(principalID); | 157 | XInventoryFolder root = GetRootXFolder(principalID); |
158 | |||
159 | if (!IsWithinSuitcaseTree(folderID, root, suitcase)) | ||
160 | return new InventoryCollection(); | ||
161 | |||
157 | if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase | 162 | if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase |
158 | { | 163 | { |
159 | XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); | ||
160 | if (suitcase != null) | 164 | if (suitcase != null) |
161 | { | 165 | { |
162 | coll = base.GetFolderContent(principalID, suitcase.folderID); | 166 | coll = base.GetFolderContent(principalID, suitcase.folderID); |
@@ -180,68 +184,69 @@ namespace OpenSim.Services.HypergridService | |||
180 | return coll; | 184 | return coll; |
181 | } | 185 | } |
182 | 186 | ||
183 | //public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) | 187 | public override List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) |
184 | //{ | 188 | { |
185 | //} | 189 | // Let's do a bit of sanity checking, more than the base service does |
190 | // make sure the given folder exists under the suitcase tree of this user | ||
191 | XInventoryFolder root = GetRootXFolder(principalID); | ||
192 | XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); | ||
186 | 193 | ||
187 | //public override bool AddFolder(InventoryFolderBase folder) | 194 | if (!IsWithinSuitcaseTree(folderID, root, suitcase)) |
188 | //{ | 195 | return new List<InventoryItemBase>(); |
189 | // // Check if it's under the Suitcase folder | 196 | |
190 | // List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner); | 197 | return base.GetFolderItems(principalID, folderID); |
191 | // InventoryFolderBase suitcase = GetRootFolder(folder.Owner); | 198 | } |
192 | // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID); | ||
193 | |||
194 | // foreach (InventoryFolderBase f in suitDescendents) | ||
195 | // if (folder.ParentID == f.ID) | ||
196 | // { | ||
197 | // XInventoryFolder xFolder = ConvertFromOpenSim(folder); | ||
198 | // return m_Database.StoreFolder(xFolder); | ||
199 | // } | ||
200 | // return false; | ||
201 | //} | ||
202 | 199 | ||
203 | private List<InventoryFolderBase> GetDescendents(List<InventoryFolderBase> lst, UUID root) | 200 | public override bool AddFolder(InventoryFolderBase folder) |
204 | { | 201 | { |
205 | List<InventoryFolderBase> direct = lst.FindAll(delegate(InventoryFolderBase f) { return f.ParentID == root; }); | 202 | // Let's do a bit of sanity checking, more than the base service does |
206 | if (direct == null) | 203 | // make sure the given folder's parent folder exists under the suitcase tree of this user |
207 | return new List<InventoryFolderBase>(); | 204 | XInventoryFolder root = GetRootXFolder(folder.Owner); |
205 | XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); | ||
208 | 206 | ||
209 | List<InventoryFolderBase> indirect = new List<InventoryFolderBase>(); | 207 | if (!IsWithinSuitcaseTree(folder.ParentID, root, suitcase)) |
210 | foreach (InventoryFolderBase f in direct) | 208 | return false; |
211 | indirect.AddRange(GetDescendents(lst, f.ID)); | ||
212 | 209 | ||
213 | direct.AddRange(indirect); | 210 | // OK, it's legit |
214 | return direct; | 211 | // Check if it's under the Root folder directly |
212 | if (folder.ParentID == root.folderID) | ||
213 | { | ||
214 | // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead | ||
215 | m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder for root folder for user {0}. Adding in suitcase instead", folder.Owner); | ||
216 | folder.ParentID = suitcase.folderID; | ||
217 | } | ||
218 | |||
219 | return base.AddFolder(folder); | ||
220 | } | ||
221 | |||
222 | public bool UpdateFolder(InventoryFolderBase folder) | ||
223 | { | ||
224 | XInventoryFolder root = GetRootXFolder(folder.Owner); | ||
225 | XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); | ||
226 | |||
227 | if (!IsWithinSuitcaseTree(folder.ID, root, suitcase)) | ||
228 | return false; | ||
229 | |||
230 | return base.UpdateFolder(folder); | ||
215 | } | 231 | } |
216 | 232 | ||
217 | // Use inherited method | 233 | public override bool MoveFolder(InventoryFolderBase folder) |
218 | //public bool UpdateFolder(InventoryFolderBase folder) | 234 | { |
219 | //{ | 235 | XInventoryFolder root = GetRootXFolder(folder.Owner); |
220 | //} | 236 | XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); |
221 | 237 | ||
222 | //public override bool MoveFolder(InventoryFolderBase folder) | 238 | if (!IsWithinSuitcaseTree(folder.ID, root, suitcase) || !IsWithinSuitcaseTree(folder.ParentID, root, suitcase)) |
223 | //{ | 239 | return false; |
224 | // XInventoryFolder[] x = m_Database.GetFolders( | 240 | |
225 | // new string[] { "folderID" }, | 241 | if (folder.ParentID == root.folderID) |
226 | // new string[] { folder.ID.ToString() }); | 242 | { |
227 | 243 | // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead | |
228 | // if (x.Length == 0) | 244 | m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveFolder to root folder for user {0}. Moving it to suitcase instead", folder.Owner); |
229 | // return false; | 245 | folder.ParentID = suitcase.folderID; |
230 | 246 | } | |
231 | // // Check if it's under the Suitcase folder | 247 | |
232 | // List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner); | 248 | return base.MoveFolder(folder); |
233 | // InventoryFolderBase suitcase = GetRootFolder(folder.Owner); | 249 | } |
234 | // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID); | ||
235 | |||
236 | // foreach (InventoryFolderBase f in suitDescendents) | ||
237 | // if (folder.ParentID == f.ID) | ||
238 | // { | ||
239 | // x[0].parentFolderID = folder.ParentID; | ||
240 | // return m_Database.StoreFolder(x[0]); | ||
241 | // } | ||
242 | |||
243 | // return false; | ||
244 | //} | ||
245 | 250 | ||
246 | public override bool DeleteFolders(UUID principalID, List<UUID> folderIDs) | 251 | public override bool DeleteFolders(UUID principalID, List<UUID> folderIDs) |
247 | { | 252 | { |
@@ -255,78 +260,110 @@ namespace OpenSim.Services.HypergridService | |||
255 | return false; | 260 | return false; |
256 | } | 261 | } |
257 | 262 | ||
258 | // Unfortunately we need to use the inherited method because of how DeRez works. | 263 | public override bool AddItem(InventoryItemBase item) |
259 | // The viewer sends the folderID hard-wired in the derez message | 264 | { |
260 | //public override bool AddItem(InventoryItemBase item) | 265 | // Let's do a bit of sanity checking, more than the base service does |
261 | //{ | 266 | // make sure the given folder's parent folder exists under the suitcase tree of this user |
262 | // // Check if it's under the Suitcase folder | 267 | XInventoryFolder root = GetRootXFolder(item.Owner); |
263 | // List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner); | 268 | XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner); |
264 | // InventoryFolderBase suitcase = GetRootFolder(item.Owner); | ||
265 | // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID); | ||
266 | 269 | ||
267 | // foreach (InventoryFolderBase f in suitDescendents) | 270 | if (!IsWithinSuitcaseTree(item.Folder, root, suitcase)) |
268 | // if (item.Folder == f.ID) | 271 | return false; |
269 | // return m_Database.StoreItem(ConvertFromOpenSim(item)); | ||
270 | 272 | ||
271 | // return false; | 273 | // OK, it's legit |
272 | //} | 274 | // Check if it's under the Root folder directly |
275 | if (item.Folder == root.folderID) | ||
276 | { | ||
277 | // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead | ||
278 | m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddItem for root folder for user {0}. Adding in suitcase instead", item.Owner); | ||
279 | item.Folder = suitcase.folderID; | ||
280 | } | ||
273 | 281 | ||
274 | //public override bool UpdateItem(InventoryItemBase item) | 282 | return base.AddItem(item); |
275 | //{ | ||
276 | // // Check if it's under the Suitcase folder | ||
277 | // List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner); | ||
278 | // InventoryFolderBase suitcase = GetRootFolder(item.Owner); | ||
279 | // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID); | ||
280 | 283 | ||
281 | // foreach (InventoryFolderBase f in suitDescendents) | 284 | } |
282 | // if (item.Folder == f.ID) | ||
283 | // return m_Database.StoreItem(ConvertFromOpenSim(item)); | ||
284 | 285 | ||
285 | // return false; | 286 | public override bool UpdateItem(InventoryItemBase item) |
286 | //} | 287 | { |
288 | XInventoryFolder root = GetRootXFolder(item.Owner); | ||
289 | XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner); | ||
287 | 290 | ||
288 | //public override bool MoveItems(UUID principalID, List<InventoryItemBase> items) | 291 | if (!IsWithinSuitcaseTree(item.Folder, root, suitcase)) |
289 | //{ | 292 | return false; |
290 | // // Principal is b0rked. *sigh* | 293 | |
291 | // // | 294 | return base.UpdateItem(item); |
292 | // // Let's assume they all have the same principal | 295 | } |
293 | // // Check if it's under the Suitcase folder | 296 | |
294 | // List<InventoryFolderBase> skel = base.GetInventorySkeleton(items[0].Owner); | 297 | public override bool MoveItems(UUID principalID, List<InventoryItemBase> items) |
295 | // InventoryFolderBase suitcase = GetRootFolder(items[0].Owner); | 298 | { |
296 | // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID); | 299 | // Principal is b0rked. *sigh* |
297 | 300 | ||
298 | // foreach (InventoryItemBase i in items) | 301 | XInventoryFolder root = GetRootXFolder(items[0].Owner); |
299 | // { | 302 | XInventoryFolder suitcase = GetSuitcaseXFolder(items[0].Owner); |
300 | // foreach (InventoryFolderBase f in suitDescendents) | 303 | |
301 | // if (i.Folder == f.ID) | 304 | if (!IsWithinSuitcaseTree(items[0].Folder, root, suitcase)) |
302 | // m_Database.MoveItem(i.ID.ToString(), i.Folder.ToString()); | 305 | return false; |
303 | // } | 306 | |
304 | 307 | foreach (InventoryItemBase it in items) | |
305 | // return true; | 308 | if (it.Folder == root.folderID) |
306 | //} | 309 | { |
310 | // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead | ||
311 | m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveItem to root folder for user {0}. Moving it to suitcase instead", it.Owner); | ||
312 | it.Folder = suitcase.folderID; | ||
313 | } | ||
314 | |||
315 | return base.MoveItems(principalID, items); | ||
316 | |||
317 | } | ||
307 | 318 | ||
308 | // Let these pass. Use inherited methods. | 319 | // Let these pass. Use inherited methods. |
309 | //public bool DeleteItems(UUID principalID, List<UUID> itemIDs) | 320 | public override bool DeleteItems(UUID principalID, List<UUID> itemIDs) |
310 | //{ | 321 | { |
311 | //} | 322 | return false; |
323 | } | ||
312 | 324 | ||
313 | //public override InventoryItemBase GetItem(InventoryItemBase item) | 325 | public override InventoryItemBase GetItem(InventoryItemBase item) |
314 | //{ | 326 | { |
315 | // InventoryItemBase it = base.GetItem(item); | 327 | InventoryItemBase it = base.GetItem(item); |
316 | // if (it != null) | 328 | XInventoryFolder root = GetRootXFolder(it.Owner); |
317 | // { | 329 | XInventoryFolder suitcase = GetSuitcaseXFolder(it.Owner); |
318 | // UserAccount user = m_Cache.GetUser(it.CreatorId); | ||
319 | |||
320 | // // Adjust the creator data | ||
321 | // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) | ||
322 | // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName; | ||
323 | // } | ||
324 | // return it; | ||
325 | //} | ||
326 | 330 | ||
327 | //public InventoryFolderBase GetFolder(InventoryFolderBase folder) | 331 | if (it != null) |
328 | //{ | 332 | { |
329 | //} | 333 | if (!IsWithinSuitcaseTree(it.Folder, root, suitcase)) |
334 | return null; | ||
335 | |||
336 | if (it.Folder == suitcase.folderID) | ||
337 | it.Folder = root.folderID; | ||
338 | |||
339 | // UserAccount user = m_Cache.GetUser(it.CreatorId); | ||
340 | |||
341 | // // Adjust the creator data | ||
342 | // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) | ||
343 | // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName; | ||
344 | //} | ||
345 | } | ||
346 | |||
347 | return it; | ||
348 | } | ||
349 | |||
350 | public override InventoryFolderBase GetFolder(InventoryFolderBase folder) | ||
351 | { | ||
352 | InventoryFolderBase f = base.GetFolder(folder); | ||
353 | XInventoryFolder root = GetRootXFolder(f.Owner); | ||
354 | XInventoryFolder suitcase = GetSuitcaseXFolder(f.Owner); | ||
355 | |||
356 | if (f != null) | ||
357 | { | ||
358 | if (!IsWithinSuitcaseTree(f.ID, root, suitcase)) | ||
359 | return null; | ||
360 | |||
361 | if (f.ParentID == suitcase.folderID) | ||
362 | f.ParentID = root.folderID; | ||
363 | } | ||
364 | |||
365 | return f; | ||
366 | } | ||
330 | 367 | ||
331 | //public List<InventoryItemBase> GetActiveGestures(UUID principalID) | 368 | //public List<InventoryItemBase> GetActiveGestures(UUID principalID) |
332 | //{ | 369 | //{ |
@@ -336,6 +373,19 @@ namespace OpenSim.Services.HypergridService | |||
336 | //{ | 373 | //{ |
337 | //} | 374 | //} |
338 | 375 | ||
376 | #region Auxiliary functions | ||
377 | private XInventoryFolder GetXFolder(UUID userID, UUID folderID) | ||
378 | { | ||
379 | XInventoryFolder[] folders = m_Database.GetFolders( | ||
380 | new string[] { "agentID", "folderID" }, | ||
381 | new string[] { userID.ToString(), folderID.ToString() }); | ||
382 | |||
383 | if (folders.Length == 0) | ||
384 | return null; | ||
385 | |||
386 | return folders[0]; | ||
387 | } | ||
388 | |||
339 | private XInventoryFolder GetRootXFolder(UUID principalID) | 389 | private XInventoryFolder GetRootXFolder(UUID principalID) |
340 | { | 390 | { |
341 | XInventoryFolder[] folders = m_Database.GetFolders( | 391 | XInventoryFolder[] folders = m_Database.GetFolders( |
@@ -364,5 +414,53 @@ namespace OpenSim.Services.HypergridService | |||
364 | suitcase.folderID = rootID; | 414 | suitcase.folderID = rootID; |
365 | suitcase.parentFolderID = UUID.Zero; | 415 | suitcase.parentFolderID = UUID.Zero; |
366 | } | 416 | } |
417 | |||
418 | private List<XInventoryFolder> GetFolderTree(UUID root) | ||
419 | { | ||
420 | List<XInventoryFolder> t = null; | ||
421 | if (m_SuitcaseTrees.TryGetValue(root, out t)) | ||
422 | return t; | ||
423 | |||
424 | t = GetFolderTreeRecursive(root); | ||
425 | m_SuitcaseTrees.AddOrUpdate(root, t, 120); | ||
426 | return t; | ||
427 | } | ||
428 | |||
429 | private List<XInventoryFolder> GetFolderTreeRecursive(UUID root) | ||
430 | { | ||
431 | List<XInventoryFolder> tree = new List<XInventoryFolder>(); | ||
432 | XInventoryFolder[] folders = m_Database.GetFolders( | ||
433 | new string[] { "parentFolderID" }, | ||
434 | new string[] { root.ToString() }); | ||
435 | |||
436 | if (folders == null || (folders != null && folders.Length == 0)) | ||
437 | return tree; // empty tree | ||
438 | else | ||
439 | { | ||
440 | foreach (XInventoryFolder f in folders) | ||
441 | { | ||
442 | tree.Add(f); | ||
443 | tree.AddRange(GetFolderTreeRecursive(f.folderID)); | ||
444 | } | ||
445 | return tree; | ||
446 | } | ||
447 | |||
448 | } | ||
449 | |||
450 | private bool IsWithinSuitcaseTree(UUID folderID, XInventoryFolder root, XInventoryFolder suitcase) | ||
451 | { | ||
452 | List<XInventoryFolder> tree = new List<XInventoryFolder>(); | ||
453 | tree.Add(root); // Warp! the tree is the real root folder plus the children of the suitcase folder | ||
454 | tree.AddRange(GetFolderTree(suitcase.folderID)); | ||
455 | XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl) | ||
456 | { | ||
457 | if (fl.folderID == folderID) return true; | ||
458 | else return false; | ||
459 | }); | ||
460 | |||
461 | if (f == null) return false; | ||
462 | else return true; | ||
463 | } | ||
464 | #endregion | ||
367 | } | 465 | } |
368 | } | 466 | } |