aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
authorMelanie2011-06-20 03:08:56 +0200
committerMelanie2011-06-20 03:08:56 +0200
commitf4f55c4d6bdbe9a86b5343159916977b331fefe0 (patch)
tree08fb85f2aa0193bf8549e684b98501c2c52faa1a /OpenSim/Region/Framework/Scenes
parentAdd some flags to control content in search better (diff)
parentMerge branch 'master' into careminster-presence-refactor (diff)
downloadopensim-SC-f4f55c4d6bdbe9a86b5343159916977b331fefe0.zip
opensim-SC-f4f55c4d6bdbe9a86b5343159916977b331fefe0.tar.gz
opensim-SC-f4f55c4d6bdbe9a86b5343159916977b331fefe0.tar.bz2
opensim-SC-f4f55c4d6bdbe9a86b5343159916977b331fefe0.tar.xz
Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs48
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs402
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs110
8 files changed, 429 insertions, 268 deletions
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index d326141..3ec4e59 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -393,6 +393,12 @@ namespace OpenSim.Region.Framework.Scenes
393 public delegate void RegionUp(GridRegion region); 393 public delegate void RegionUp(GridRegion region);
394 public event RegionUp OnRegionUp; 394 public event RegionUp OnRegionUp;
395 395
396 public delegate void LoginsEnabled(string regionName);
397 public event LoginsEnabled OnLoginsEnabled;
398
399 public delegate void PrimsLoaded(Scene s);
400 public event PrimsLoaded OnPrimsLoaded;
401
396 public class MoneyTransferArgs : EventArgs 402 public class MoneyTransferArgs : EventArgs
397 { 403 {
398 public UUID sender; 404 public UUID sender;
@@ -2242,5 +2248,47 @@ namespace OpenSim.Region.Framework.Scenes
2242 } 2248 }
2243 } 2249 }
2244 } 2250 }
2251
2252 public void TriggerLoginsEnabled (string regionName)
2253 {
2254 LoginsEnabled handler = OnLoginsEnabled;
2255
2256 if ( handler != null)
2257 {
2258 foreach (LoginsEnabled d in handler.GetInvocationList())
2259 {
2260 try
2261 {
2262 d(regionName);
2263 }
2264 catch (Exception e)
2265 {
2266 m_log.ErrorFormat("[EVENT MANAGER]: Delegate for LoginsEnabled failed - continuing {0} - {1}",
2267 e.Message, e.StackTrace);
2268 }
2269 }
2270 }
2271 }
2272
2273 public void TriggerPrimsLoaded(Scene s)
2274 {
2275 PrimsLoaded handler = OnPrimsLoaded;
2276
2277 if (handler != null)
2278 {
2279 foreach (PrimsLoaded d in handler.GetInvocationList())
2280 {
2281 try
2282 {
2283 d(s);
2284 }
2285 catch (Exception e)
2286 {
2287 m_log.ErrorFormat("[EVENT MANAGER]: Delegate for PrimsLoaded failed - continuing {0} - {1}",
2288 e.Message, e.StackTrace);
2289 }
2290 }
2291 }
2292 }
2245 } 2293 }
2246} 2294}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 0b92818..c04bbb4 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -408,192 +408,198 @@ namespace OpenSim.Region.Framework.Scenes
408 InventoryItemBase item = new InventoryItemBase(itemId, senderId); 408 InventoryItemBase item = new InventoryItemBase(itemId, senderId);
409 item = InventoryService.GetItem(item); 409 item = InventoryService.GetItem(item);
410 410
411 if ((item != null) && (item.Owner == senderId)) 411 if (item == null)
412 { 412 {
413 IUserManagement uman = RequestModuleInterface<IUserManagement>(); 413 m_log.WarnFormat(
414 if (uman != null) 414 "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient);
415 uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); 415 return null;
416 }
416 417
417 if (!Permissions.BypassPermissions()) 418 if (item.Owner != senderId)
418 { 419 {
419 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) 420 m_log.WarnFormat(
420 return null; 421 "[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}",
421 } 422 item.Name, item.ID, recipient, senderId, item.Owner);
423 return null;
424 }
425
426 IUserManagement uman = RequestModuleInterface<IUserManagement>();
427 if (uman != null)
428 uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
429
430 if (!Permissions.BypassPermissions())
431 {
432 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
433 return null;
434 }
422 435
423 // Insert a copy of the item into the recipient 436 // Insert a copy of the item into the recipient
424 InventoryItemBase itemCopy = new InventoryItemBase(); 437 InventoryItemBase itemCopy = new InventoryItemBase();
425 itemCopy.Owner = recipient; 438 itemCopy.Owner = recipient;
426 itemCopy.CreatorId = item.CreatorId; 439 itemCopy.CreatorId = item.CreatorId;
427 itemCopy.CreatorData = item.CreatorData; 440 itemCopy.CreatorData = item.CreatorData;
428 itemCopy.ID = UUID.Random(); 441 itemCopy.ID = UUID.Random();
429 itemCopy.AssetID = item.AssetID; 442 itemCopy.AssetID = item.AssetID;
430 itemCopy.Description = item.Description; 443 itemCopy.Description = item.Description;
431 itemCopy.Name = item.Name; 444 itemCopy.Name = item.Name;
432 itemCopy.AssetType = item.AssetType; 445 itemCopy.AssetType = item.AssetType;
433 itemCopy.InvType = item.InvType; 446 itemCopy.InvType = item.InvType;
434 itemCopy.Folder = recipientFolderId; 447 itemCopy.Folder = recipientFolderId;
435 448
436 if (Permissions.PropagatePermissions() && recipient != senderId) 449 if (Permissions.PropagatePermissions() && recipient != senderId)
450 {
451 // Trying to do this right this time. This is evil. If
452 // you believe in Good, go elsewhere. Vampires and other
453 // evil creatores only beyond this point. You have been
454 // warned.
455
456 // We're going to mask a lot of things by the next perms
457 // Tweak the next perms to be nicer to our data
458 //
459 // In this mask, all the bits we do NOT want to mess
460 // with are set. These are:
461 //
462 // Transfer
463 // Copy
464 // Modufy
465 uint permsMask = ~ ((uint)PermissionMask.Copy |
466 (uint)PermissionMask.Transfer |
467 (uint)PermissionMask.Modify);
468
469 // Now, reduce the next perms to the mask bits
470 // relevant to the operation
471 uint nextPerms = permsMask | (item.NextPermissions &
472 ((uint)PermissionMask.Copy |
473 (uint)PermissionMask.Transfer |
474 (uint)PermissionMask.Modify));
475
476 // nextPerms now has all bits set, except for the actual
477 // next permission bits.
478
479 // This checks for no mod, no copy, no trans.
480 // This indicates an error or messed up item. Do it like
481 // SL and assume trans
482 if (nextPerms == permsMask)
483 nextPerms |= (uint)PermissionMask.Transfer;
484
485 // Inventory owner perms are the logical AND of the
486 // folded perms and the root prim perms, however, if
487 // the root prim is mod, the inventory perms will be
488 // mod. This happens on "take" and is of little concern
489 // here, save for preventing escalation
490
491 // This hack ensures that items previously permalocked
492 // get unlocked when they're passed or rezzed
493 uint basePerms = item.BasePermissions |
494 (uint)PermissionMask.Move;
495 uint ownerPerms = item.CurrentPermissions;
496
497 // If this is an object, root prim perms may be more
498 // permissive than folded perms. Use folded perms as
499 // a mask
500 if (item.InvType == (int)InventoryType.Object)
437 { 501 {
438 // Trying to do this right this time. This is evil. If 502 // Create a safe mask for the current perms
439 // you believe in Good, go elsewhere. Vampires and other 503 uint foldedPerms = (item.CurrentPermissions & 7) << 13;
440 // evil creatores only beyond this point. You have been 504 foldedPerms |= permsMask;
441 // warned. 505
442 506 bool isRootMod = (item.CurrentPermissions &
443 // We're going to mask a lot of things by the next perms 507 (uint)PermissionMask.Modify) != 0 ?
444 // Tweak the next perms to be nicer to our data 508 true : false;
445 // 509
446 // In this mask, all the bits we do NOT want to mess 510 // Mask the owner perms to the folded perms
447 // with are set. These are: 511 ownerPerms &= foldedPerms;
448 // 512 basePerms &= foldedPerms;
449 // Transfer 513
450 // Copy 514 // If the root was mod, let the mask reflect that
451 // Modufy 515 // We also need to adjust the base here, because
452 uint permsMask = ~ ((uint)PermissionMask.Copy | 516 // we should be able to edit in-inventory perms
453 (uint)PermissionMask.Transfer | 517 // for the root prim, if it's mod.
454 (uint)PermissionMask.Modify); 518 if (isRootMod)
455
456 // Now, reduce the next perms to the mask bits
457 // relevant to the operation
458 uint nextPerms = permsMask | (item.NextPermissions &
459 ((uint)PermissionMask.Copy |
460 (uint)PermissionMask.Transfer |
461 (uint)PermissionMask.Modify));
462
463 // nextPerms now has all bits set, except for the actual
464 // next permission bits.
465
466 // This checks for no mod, no copy, no trans.
467 // This indicates an error or messed up item. Do it like
468 // SL and assume trans
469 if (nextPerms == permsMask)
470 nextPerms |= (uint)PermissionMask.Transfer;
471
472 // Inventory owner perms are the logical AND of the
473 // folded perms and the root prim perms, however, if
474 // the root prim is mod, the inventory perms will be
475 // mod. This happens on "take" and is of little concern
476 // here, save for preventing escalation
477
478 // This hack ensures that items previously permalocked
479 // get unlocked when they're passed or rezzed
480 uint basePerms = item.BasePermissions |
481 (uint)PermissionMask.Move;
482 uint ownerPerms = item.CurrentPermissions;
483
484 // If this is an object, root prim perms may be more
485 // permissive than folded perms. Use folded perms as
486 // a mask
487 if (item.InvType == (int)InventoryType.Object)
488 { 519 {
489 // Create a safe mask for the current perms 520 ownerPerms |= (uint)PermissionMask.Modify;
490 uint foldedPerms = (item.CurrentPermissions & 7) << 13; 521 basePerms |= (uint)PermissionMask.Modify;
491 foldedPerms |= permsMask;
492
493 bool isRootMod = (item.CurrentPermissions &
494 (uint)PermissionMask.Modify) != 0 ?
495 true : false;
496
497 // Mask the owner perms to the folded perms
498 ownerPerms &= foldedPerms;
499 basePerms &= foldedPerms;
500
501 // If the root was mod, let the mask reflect that
502 // We also need to adjust the base here, because
503 // we should be able to edit in-inventory perms
504 // for the root prim, if it's mod.
505 if (isRootMod)
506 {
507 ownerPerms |= (uint)PermissionMask.Modify;
508 basePerms |= (uint)PermissionMask.Modify;
509 }
510 } 522 }
523 }
511 524
512 // These will be applied to the root prim at next rez. 525 // These will be applied to the root prim at next rez.
513 // The slam bit (bit 3) and folded permission (bits 0-2) 526 // The slam bit (bit 3) and folded permission (bits 0-2)
514 // are preserved due to the above mangling 527 // are preserved due to the above mangling
515 ownerPerms &= nextPerms; 528 ownerPerms &= nextPerms;
516 529
517 // Mask the base permissions. This is a conservative 530 // Mask the base permissions. This is a conservative
518 // approach altering only the three main perms 531 // approach altering only the three main perms
519 basePerms &= nextPerms; 532 basePerms &= nextPerms;
520 533
521 // Assign to the actual item. Make sure the slam bit is 534 // Assign to the actual item. Make sure the slam bit is
522 // set, if it wasn't set before. 535 // set, if it wasn't set before.
523 itemCopy.BasePermissions = basePerms; 536 itemCopy.BasePermissions = basePerms;
524 itemCopy.CurrentPermissions = ownerPerms; 537 itemCopy.CurrentPermissions = ownerPerms;
525 itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; 538 itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
526 539
527 itemCopy.NextPermissions = item.NextPermissions; 540 itemCopy.NextPermissions = item.NextPermissions;
528 541
529 // This preserves "everyone can move" 542 // This preserves "everyone can move"
530 itemCopy.EveryOnePermissions = item.EveryOnePermissions & 543 itemCopy.EveryOnePermissions = item.EveryOnePermissions &
531 nextPerms; 544 nextPerms;
532 545
533 // Intentionally killing "share with group" here, as 546 // Intentionally killing "share with group" here, as
534 // the recipient will not have the group this is 547 // the recipient will not have the group this is
535 // set to 548 // set to
536 itemCopy.GroupPermissions = 0; 549 itemCopy.GroupPermissions = 0;
537 } 550 }
538 else 551 else
552 {
553 itemCopy.CurrentPermissions = item.CurrentPermissions;
554 itemCopy.NextPermissions = item.NextPermissions;
555 itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
556 itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
557 itemCopy.BasePermissions = item.BasePermissions;
558 }
559
560 if (itemCopy.Folder == UUID.Zero)
561 {
562 InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
563
564 if (folder != null)
539 { 565 {
540 itemCopy.CurrentPermissions = item.CurrentPermissions; 566 itemCopy.Folder = folder.ID;
541 itemCopy.NextPermissions = item.NextPermissions;
542 itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
543 itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
544 itemCopy.BasePermissions = item.BasePermissions;
545 } 567 }
546 568 else
547 if (itemCopy.Folder == UUID.Zero)
548 { 569 {
549 InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); 570 InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
550 571
551 if (folder != null) 572 if (root != null)
552 { 573 itemCopy.Folder = root.ID;
553 itemCopy.Folder = folder.ID;
554 }
555 else 574 else
556 { 575 return null; // No destination
557 InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
558
559 if (root != null)
560 itemCopy.Folder = root.ID;
561 else
562 return null; // No destination
563 }
564 } 576 }
577 }
565 578
566 itemCopy.GroupID = UUID.Zero; 579 itemCopy.GroupID = UUID.Zero;
567 itemCopy.GroupOwned = false; 580 itemCopy.GroupOwned = false;
568 itemCopy.Flags = item.Flags; 581 itemCopy.Flags = item.Flags;
569 itemCopy.SalePrice = item.SalePrice; 582 itemCopy.SalePrice = item.SalePrice;
570 itemCopy.SaleType = item.SaleType; 583 itemCopy.SaleType = item.SaleType;
571 584
572 if (AddInventoryItem(itemCopy)) 585 if (AddInventoryItem(itemCopy))
573 { 586 {
574 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); 587 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
575 if (invAccess != null) 588 if (invAccess != null)
576 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); 589 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
577 } 590 }
578 591
579 if (!Permissions.BypassPermissions()) 592 if (!Permissions.BypassPermissions())
593 {
594 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
580 { 595 {
581 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 596 List<UUID> items = new List<UUID>();
582 { 597 items.Add(itemId);
583 List<UUID> items = new List<UUID>(); 598 InventoryService.DeleteItems(senderId, items);
584 items.Add(itemId);
585 InventoryService.DeleteItems(senderId, items);
586 }
587 } 599 }
588
589 return itemCopy;
590 }
591 else
592 {
593 m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId);
594 return null;
595 } 600 }
596 601
602 return itemCopy;
597 } 603 }
598 604
599 /// <summary> 605 /// <summary>
@@ -781,7 +787,7 @@ namespace OpenSim.Region.Framework.Scenes
781 /// <param name="asset"></param> 787 /// <param name="asset"></param>
782 /// <param name="invType"></param> 788 /// <param name="invType"></param>
783 /// <param name="nextOwnerMask"></param> 789 /// <param name="nextOwnerMask"></param>
784 private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, 790 public void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
785 AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate) 791 AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
786 { 792 {
787 CreateNewInventoryItem( 793 CreateNewInventoryItem(
@@ -836,78 +842,6 @@ namespace OpenSim.Region.Framework.Scenes
836 } 842 }
837 843
838 /// <summary> 844 /// <summary>
839 /// Create a new inventory item. Called when the client creates a new item directly within their
840 /// inventory (e.g. by selecting a context inventory menu option).
841 /// </summary>
842 /// <param name="remoteClient"></param>
843 /// <param name="transactionID"></param>
844 /// <param name="folderID"></param>
845 /// <param name="callbackID"></param>
846 /// <param name="description"></param>
847 /// <param name="name"></param>
848 /// <param name="invType"></param>
849 /// <param name="type"></param>
850 /// <param name="wearableType"></param>
851 /// <param name="nextOwnerMask"></param>
852 public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
853 uint callbackID, string description, string name, sbyte invType,
854 sbyte assetType,
855 byte wearableType, uint nextOwnerMask, int creationDate)
856 {
857 m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
858
859 if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
860 return;
861
862 InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
863 InventoryFolderBase folder = InventoryService.GetFolder(f);
864
865 if (folder == null || folder.Owner != remoteClient.AgentId)
866 return;
867
868 if (transactionID == UUID.Zero)
869 {
870 ScenePresence presence;
871 if (TryGetScenePresence(remoteClient.AgentId, out presence))
872 {
873 byte[] data = null;
874
875 if (invType == (sbyte)InventoryType.Landmark && presence != null)
876 {
877 Vector3 pos = presence.AbsolutePosition;
878 string strdata = String.Format(
879 "Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
880 presence.Scene.RegionInfo.RegionID,
881 pos.X, pos.Y, pos.Z,
882 presence.RegionHandle);
883 data = Encoding.ASCII.GetBytes(strdata);
884 }
885
886 AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId);
887 AssetService.Store(asset);
888
889 CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
890 }
891 else
892 {
893 m_log.ErrorFormat(
894 "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
895 remoteClient.AgentId);
896 }
897 }
898 else
899 {
900 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
901 if (agentTransactions != null)
902 {
903 agentTransactions.HandleItemCreationFromTransaction(
904 remoteClient, transactionID, folderID, callbackID, description,
905 name, invType, assetType, wearableType, nextOwnerMask);
906 }
907 }
908 }
909
910 /// <summary>
911 /// Link an inventory item to an existing item. 845 /// Link an inventory item to an existing item.
912 /// </summary> 846 /// </summary>
913 /// <remarks> 847 /// <remarks>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 254ad05..1575e50 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -95,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes
95 public bool m_strictAccessControl = true; 95 public bool m_strictAccessControl = true;
96 public bool m_seeIntoBannedRegion = false; 96 public bool m_seeIntoBannedRegion = false;
97 public int MaxUndoCount = 5; 97 public int MaxUndoCount = 5;
98 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
99 public bool LoginLock = false;
98 public bool LoginsDisabled = true; 100 public bool LoginsDisabled = true;
101 public bool StartDisabled = false;
99 public bool LoadingPrims; 102 public bool LoadingPrims;
100 public IXfer XferManager; 103 public IXfer XferManager;
101 104
@@ -1399,10 +1402,26 @@ namespace OpenSim.Region.Framework.Scenes
1399 IConfig startupConfig = m_config.Configs["Startup"]; 1402 IConfig startupConfig = m_config.Configs["Startup"];
1400 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) 1403 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1401 { 1404 {
1405 // This handles a case of a region having no scripts for the RegionReady module
1406 if (m_sceneGraph.GetActiveScriptsCount() == 0)
1407 {
1408 // need to be able to tell these have changed in RegionReady
1409 LoginLock = false;
1410 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
1411 }
1402 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); 1412 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1403 LoginsDisabled = false; 1413 // For RegionReady lockouts
1414 if( LoginLock == false)
1415 {
1416 LoginsDisabled = false;
1417 }
1404 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo); 1418 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1405 } 1419 }
1420 else
1421 {
1422 StartDisabled = true;
1423 LoginsDisabled = true;
1424 }
1406 } 1425 }
1407 } 1426 }
1408 catch (NotImplementedException) 1427 catch (NotImplementedException)
@@ -1765,6 +1784,7 @@ namespace OpenSim.Region.Framework.Scenes
1765 1784
1766 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); 1785 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
1767 LoadingPrims = false; 1786 LoadingPrims = false;
1787 EventManager.TriggerPrimsLoaded(this);
1768 } 1788 }
1769 1789
1770 1790
@@ -1930,6 +1950,10 @@ namespace OpenSim.Region.Framework.Scenes
1930 sceneObject.SetGroup(groupID, null); 1950 sceneObject.SetGroup(groupID, null);
1931 } 1951 }
1932 1952
1953 IUserManagement uman = RequestModuleInterface<IUserManagement>();
1954 if (uman != null)
1955 sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
1956
1933 sceneObject.ScheduleGroupForFullUpdate(); 1957 sceneObject.ScheduleGroupForFullUpdate();
1934 1958
1935 return sceneObject; 1959 return sceneObject;
@@ -2658,6 +2682,10 @@ namespace OpenSim.Region.Framework.Scenes
2658 if (TryGetScenePresence(client.AgentId, out presence)) 2682 if (TryGetScenePresence(client.AgentId, out presence))
2659 { 2683 {
2660 m_LastLogin = Util.EnvironmentTickCount(); 2684 m_LastLogin = Util.EnvironmentTickCount();
2685
2686 // Cache the user's name
2687 CacheUserName(aCircuit);
2688
2661 EventManager.TriggerOnNewClient(client); 2689 EventManager.TriggerOnNewClient(client);
2662 if (vialogin) 2690 if (vialogin)
2663 { 2691 {
@@ -2671,6 +2699,28 @@ namespace OpenSim.Region.Framework.Scenes
2671 } 2699 }
2672 } 2700 }
2673 2701
2702 private void CacheUserName(AgentCircuitData aCircuit)
2703 {
2704 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
2705 if (uMan != null)
2706 {
2707 string homeURL = string.Empty;
2708 string first = aCircuit.firstname, last = aCircuit.lastname;
2709 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
2710 homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
2711 if (aCircuit.lastname.StartsWith("@"))
2712 {
2713 string[] parts = aCircuit.firstname.Split('.');
2714 if (parts.Length >= 2)
2715 {
2716 first = parts[0];
2717 last = parts[1];
2718 }
2719 }
2720 uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
2721 }
2722 }
2723
2674 private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin) 2724 private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
2675 { 2725 {
2676 vialogin = false; 2726 vialogin = false;
@@ -2813,7 +2863,7 @@ namespace OpenSim.Region.Framework.Scenes
2813 2863
2814 public virtual void SubscribeToClientInventoryEvents(IClientAPI client) 2864 public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
2815 { 2865 {
2816 client.OnCreateNewInventoryItem += CreateNewInventoryItem; 2866
2817 client.OnLinkInventoryItem += HandleLinkInventoryItem; 2867 client.OnLinkInventoryItem += HandleLinkInventoryItem;
2818 client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder; 2868 client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
2819 client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder; 2869 client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
@@ -2837,7 +2887,6 @@ namespace OpenSim.Region.Framework.Scenes
2837 public virtual void SubscribeToClientTeleportEvents(IClientAPI client) 2887 public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
2838 { 2888 {
2839 client.OnTeleportLocationRequest += RequestTeleportLocation; 2889 client.OnTeleportLocationRequest += RequestTeleportLocation;
2840 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
2841 } 2890 }
2842 2891
2843 public virtual void SubscribeToClientScriptEvents(IClientAPI client) 2892 public virtual void SubscribeToClientScriptEvents(IClientAPI client)
@@ -2941,7 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
2941 2990
2942 public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client) 2991 public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
2943 { 2992 {
2944 client.OnCreateNewInventoryItem -= CreateNewInventoryItem; 2993
2945 client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder; 2994 client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
2946 client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder; 2995 client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
2947 client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!! 2996 client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
@@ -2963,7 +3012,7 @@ namespace OpenSim.Region.Framework.Scenes
2963 public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client) 3012 public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
2964 { 3013 {
2965 client.OnTeleportLocationRequest -= RequestTeleportLocation; 3014 client.OnTeleportLocationRequest -= RequestTeleportLocation;
2966 client.OnTeleportLandmarkRequest -= RequestTeleportLandmark; 3015 //client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
2967 //client.OnTeleportHomeRequest -= TeleportClientHome; 3016 //client.OnTeleportHomeRequest -= TeleportClientHome;
2968 } 3017 }
2969 3018
@@ -4064,26 +4113,6 @@ namespace OpenSim.Region.Framework.Scenes
4064 } 4113 }
4065 } 4114 }
4066 4115
4067 /// <summary>
4068 /// Tries to teleport agent to landmark.
4069 /// </summary>
4070 /// <param name="remoteClient"></param>
4071 /// <param name="regionHandle"></param>
4072 /// <param name="position"></param>
4073 public void RequestTeleportLandmark(IClientAPI remoteClient, UUID regionID, Vector3 position)
4074 {
4075 GridRegion info = GridService.GetRegionByUUID(UUID.Zero, regionID);
4076
4077 if (info == null)
4078 {
4079 // can't find the region: Tell viewer and abort
4080 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
4081 return;
4082 }
4083
4084 RequestTeleportLocation(remoteClient, info.RegionHandle, position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark));
4085 }
4086
4087 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) 4116 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
4088 { 4117 {
4089 if (m_teleportModule != null) 4118 if (m_teleportModule != null)
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index c0236f4..39d4a29 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -1584,7 +1584,7 @@ namespace OpenSim.Region.Framework.Scenes
1584 } 1584 }
1585 1585
1586 /// <summary> 1586 /// <summary>
1587 /// 1587 /// Handle a prim description set request from a viewer.
1588 /// </summary> 1588 /// </summary>
1589 /// <param name="primLocalID"></param> 1589 /// <param name="primLocalID"></param>
1590 /// <param name="description"></param> 1590 /// <param name="description"></param>
@@ -1601,8 +1601,17 @@ namespace OpenSim.Region.Framework.Scenes
1601 } 1601 }
1602 } 1602 }
1603 1603
1604 /// <summary>
1605 /// Set a click action for the prim.
1606 /// </summary>
1607 /// <param name="remoteClient"></param>
1608 /// <param name="primLocalID"></param>
1609 /// <param name="clickAction"></param>
1604 protected internal void PrimClickAction(IClientAPI remoteClient, uint primLocalID, string clickAction) 1610 protected internal void PrimClickAction(IClientAPI remoteClient, uint primLocalID, string clickAction)
1605 { 1611 {
1612// m_log.DebugFormat(
1613// "[SCENEGRAPH]: User {0} set click action for {1} to {2}", remoteClient.Name, primLocalID, clickAction);
1614
1606 SceneObjectGroup group = GetGroupByPrim(primLocalID); 1615 SceneObjectGroup group = GetGroupByPrim(primLocalID);
1607 if (group != null) 1616 if (group != null)
1608 { 1617 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 74d24a6..482597d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -563,6 +563,11 @@ namespace OpenSim.Region.Framework.Scenes
563 563
564 #endregion 564 #endregion
565 565
566// ~SceneObjectGroup()
567// {
568// m_log.DebugFormat("[SCENE OBJECT GROUP]: Destructor called for {0}, local id {1}", Name, LocalId);
569// }
570
566 #region Constructors 571 #region Constructors
567 572
568 /// <summary> 573 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index cb321aa..e3744bd 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -357,6 +357,13 @@ namespace OpenSim.Region.Framework.Scenes
357 357
358 #endregion Fields 358 #endregion Fields
359 359
360// ~SceneObjectPart()
361// {
362// m_log.DebugFormat(
363// "[SCENE OBJECT PART]: Destructor called for {0}, local id {1}, parent {2} {3}",
364// Name, LocalId, ParentGroup.Name, ParentGroup.LocalId);
365// }
366
360 #region Constructors 367 #region Constructors
361 368
362 /// <summary> 369 /// <summary>
@@ -1636,7 +1643,6 @@ namespace OpenSim.Region.Framework.Scenes
1636 { 1643 {
1637 PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info 1644 PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
1638 PhysActor.SOPDescription = this.Description; 1645 PhysActor.SOPDescription = this.Description;
1639 PhysActor.LocalID = LocalId;
1640 DoPhysicsPropertyUpdate(RigidBody, true); 1646 DoPhysicsPropertyUpdate(RigidBody, true);
1641 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1647 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
1642 } 1648 }
@@ -4428,6 +4434,7 @@ namespace OpenSim.Region.Framework.Scenes
4428 { 4434 {
4429 // It's not phantom anymore. So make sure the physics engine get's knowledge of it 4435 // It's not phantom anymore. So make sure the physics engine get's knowledge of it
4430 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( 4436 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
4437 LocalId,
4431 string.Format("{0}/{1}", Name, UUID), 4438 string.Format("{0}/{1}", Name, UUID),
4432 Shape, 4439 Shape,
4433 AbsolutePosition, 4440 AbsolutePosition,
@@ -4439,7 +4446,6 @@ namespace OpenSim.Region.Framework.Scenes
4439 pa = PhysActor; 4446 pa = PhysActor;
4440 if (pa != null) 4447 if (pa != null)
4441 { 4448 {
4442 pa.LocalID = LocalId;
4443 DoPhysicsPropertyUpdate(UsePhysics, true); 4449 DoPhysicsPropertyUpdate(UsePhysics, true);
4444 if (m_parentGroup != null) 4450 if (m_parentGroup != null)
4445 { 4451 {
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 95ded7f..9174070 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -121,7 +121,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
121 } 121 }
122 } 122 }
123 123
124
125 /// <summary> 124 /// <summary>
126 /// Serialize a scene object to the original xml format 125 /// Serialize a scene object to the original xml format
127 /// </summary> 126 /// </summary>
@@ -572,7 +571,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
572 571
573 private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) 572 private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
574 { 573 {
575 obj.Shape = ReadShape(reader, "Shape"); 574 bool errors = false;
575 obj.Shape = ReadShape(reader, "Shape", out errors);
576
577 if (errors)
578 m_log.DebugFormat(
579 "[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors. Please see earlier log entries.",
580 obj.Name, obj.UUID);
576 } 581 }
577 582
578 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) 583 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
@@ -1173,7 +1178,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1173 writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture)); 1178 writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture));
1174 writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture)); 1179 writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture));
1175 writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture)); 1180 writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture));
1176 writer.WriteElementString("A", sop.Color.G.ToString(Utils.EnUsCulture)); 1181 writer.WriteElementString("A", sop.Color.A.ToString(Utils.EnUsCulture));
1177 writer.WriteEndElement(); 1182 writer.WriteEndElement();
1178 1183
1179 writer.WriteElementString("Text", sop.Text); 1184 writer.WriteElementString("Text", sop.Text);
@@ -1479,7 +1484,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1479 } 1484 }
1480 catch (Exception e) 1485 catch (Exception e)
1481 { 1486 {
1482 m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing {0}: {1}", nodeName, e); 1487 m_log.DebugFormat(
1488 "[SceneObjectSerializer]: exception while parsing {0} in object {1} {2}: {3}{4}",
1489 obj.Name, obj.UUID, nodeName, e.Message, e.StackTrace);
1483 if (reader.NodeType == XmlNodeType.EndElement) 1490 if (reader.NodeType == XmlNodeType.EndElement)
1484 reader.Read(); 1491 reader.Read();
1485 } 1492 }
@@ -1531,8 +1538,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1531 return tinv; 1538 return tinv;
1532 } 1539 }
1533 1540
1534 static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name) 1541 /// <summary>
1542 /// Read a shape from xml input
1543 /// </summary>
1544 /// <param name="reader"></param>
1545 /// <param name="name">The name of the xml element containing the shape</param>
1546 /// <param name="errors">true if any errors were encountered during parsing, false otherwise</param>
1547 /// <returns>The shape parsed</returns>
1548 static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
1535 { 1549 {
1550 errors = false;
1551
1536 PrimitiveBaseShape shape = new PrimitiveBaseShape(); 1552 PrimitiveBaseShape shape = new PrimitiveBaseShape();
1537 1553
1538 reader.ReadStartElement(name, String.Empty); // Shape 1554 reader.ReadStartElement(name, String.Empty); // Shape
@@ -1551,7 +1567,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1551 } 1567 }
1552 catch (Exception e) 1568 catch (Exception e)
1553 { 1569 {
1554 m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing Shape {0}: {1}", nodeName, e); 1570 errors = true;
1571 m_log.DebugFormat(
1572 "[SceneObjectSerializer]: exception while parsing Shape property {0}: {1}{2}",
1573 nodeName, e.Message, e.StackTrace);
1574
1555 if (reader.NodeType == XmlNodeType.EndElement) 1575 if (reader.NodeType == XmlNodeType.EndElement)
1556 reader.Read(); 1576 reader.Read();
1557 } 1577 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
new file mode 100644
index 0000000..abca792
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -0,0 +1,110 @@
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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using System.Threading;
33using System.Timers;
34using Timer=System.Timers.Timer;
35using Nini.Config;
36using NUnit.Framework;
37using OpenMetaverse;
38using OpenMetaverse.Assets;
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
44using OpenSim.Region.CoreModules.World.Serialiser;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49
50namespace OpenSim.Region.Framework.Tests
51{
52 [TestFixture]
53 public class UserInventoryTests
54 {
55 [Test]
56 public void TestGiveInventoryItem()
57 {
58 TestHelper.InMethod();
59// log4net.Config.XmlConfigurator.Configure();
60
61 Scene scene = SceneSetupHelpers.SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001);
63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002);
64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID);
65
66 scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID);
67
68 InventoryItemBase retrievedItem1
69 = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Notecards/item1");
70
71 Assert.That(retrievedItem1, Is.Not.Null);
72
73 // Try giving back the freshly received item
74 scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID);
75
76 List<InventoryItemBase> reretrievedItems
77 = UserInventoryHelpers.GetInventoryItems(scene.InventoryService, user1.PrincipalID, "Notecards/item1");
78
79 Assert.That(reretrievedItems.Count, Is.EqualTo(2));
80 }
81
82 [Test]
83 public void TestGiveInventoryFolder()
84 {
85 TestHelper.InMethod();
86// log4net.Config.XmlConfigurator.Configure();
87
88 Scene scene = SceneSetupHelpers.SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001);
90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002);
91 InventoryFolderBase folder1
92 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1");
93
94 scene.GiveInventoryFolder(user2.PrincipalID, user1.PrincipalID, folder1.ID, UUID.Zero);
95
96 InventoryFolderBase retrievedFolder1
97 = UserInventoryHelpers.GetInventoryFolder(scene.InventoryService, user2.PrincipalID, "folder1");
98
99 Assert.That(retrievedFolder1, Is.Not.Null);
100
101 // Try giving back the freshly received folder
102 scene.GiveInventoryFolder(user1.PrincipalID, user2.PrincipalID, retrievedFolder1.ID, UUID.Zero);
103
104 List<InventoryFolderBase> reretrievedFolders
105 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, "folder1");
106
107 Assert.That(reretrievedFolders.Count, Is.EqualTo(2));
108 }
109 }
110} \ No newline at end of file