aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs126
-rw-r--r--OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs16
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs779
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs319
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs222
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs120
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs93
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs22
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs36
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs102
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs913
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs14
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs47
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs88
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs25
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs17
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs20
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs81
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs8
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs82
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs20
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs30
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Access/AccessModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs106
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs24
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs55
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs54
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs50
-rw-r--r--OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs93
-rw-r--r--OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs221
50 files changed, 2682 insertions, 1224 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index d85d727..8e2dba4 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -313,7 +313,9 @@ namespace Flotsam.RegionModules.AssetCache
313 } 313 }
314 catch (Exception e) 314 catch (Exception e)
315 { 315 {
316 LogException(e); 316 m_log.ErrorFormat(
317 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
318 asset.ID, e.Message, e.StackTrace);
317 } 319 }
318 } 320 }
319 } 321 }
@@ -368,13 +370,13 @@ namespace Flotsam.RegionModules.AssetCache
368 370
369 asset = (AssetBase)bformatter.Deserialize(stream); 371 asset = (AssetBase)bformatter.Deserialize(stream);
370 372
371 UpdateMemoryCache(id, asset);
372
373 m_DiskHits++; 373 m_DiskHits++;
374 } 374 }
375 catch (System.Runtime.Serialization.SerializationException e) 375 catch (System.Runtime.Serialization.SerializationException e)
376 { 376 {
377 LogException(e); 377 m_log.ErrorFormat(
378 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
379 filename, id, e.Message, e.StackTrace);
378 380
379 // If there was a problem deserializing the asset, the asset may 381 // If there was a problem deserializing the asset, the asset may
380 // either be corrupted OR was serialized under an old format 382 // either be corrupted OR was serialized under an old format
@@ -384,7 +386,9 @@ namespace Flotsam.RegionModules.AssetCache
384 } 386 }
385 catch (Exception e) 387 catch (Exception e)
386 { 388 {
387 LogException(e); 389 m_log.ErrorFormat(
390 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
391 filename, id, e.Message, e.StackTrace);
388 } 392 }
389 finally 393 finally
390 { 394 {
@@ -393,7 +397,6 @@ namespace Flotsam.RegionModules.AssetCache
393 } 397 }
394 } 398 }
395 399
396
397#if WAIT_ON_INPROGRESS_REQUESTS 400#if WAIT_ON_INPROGRESS_REQUESTS
398 // Check if we're already downloading this asset. If so, try to wait for it to 401 // Check if we're already downloading this asset. If so, try to wait for it to
399 // download. 402 // download.
@@ -416,7 +419,6 @@ namespace Flotsam.RegionModules.AssetCache
416 m_RequestsForInprogress++; 419 m_RequestsForInprogress++;
417 } 420 }
418#endif 421#endif
419
420 return asset; 422 return asset;
421 } 423 }
422 424
@@ -428,9 +430,15 @@ namespace Flotsam.RegionModules.AssetCache
428 430
429 if (m_MemoryCacheEnabled) 431 if (m_MemoryCacheEnabled)
430 asset = GetFromMemoryCache(id); 432 asset = GetFromMemoryCache(id);
431 else if (m_FileCacheEnabled) 433
434 if (asset == null && m_FileCacheEnabled)
435 {
432 asset = GetFromFileCache(id); 436 asset = GetFromFileCache(id);
433 437
438 if (m_MemoryCacheEnabled && asset != null)
439 UpdateMemoryCache(id, asset);
440 }
441
434 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) 442 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
435 { 443 {
436 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; 444 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0;
@@ -445,7 +453,6 @@ namespace Flotsam.RegionModules.AssetCache
445 } 453 }
446 454
447 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress); 455 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress);
448
449 } 456 }
450 457
451 return asset; 458 return asset;
@@ -459,7 +466,7 @@ namespace Flotsam.RegionModules.AssetCache
459 public void Expire(string id) 466 public void Expire(string id)
460 { 467 {
461 if (m_LogLevel >= 2) 468 if (m_LogLevel >= 2)
462 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}.", id); 469 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}", id);
463 470
464 try 471 try
465 { 472 {
@@ -477,7 +484,9 @@ namespace Flotsam.RegionModules.AssetCache
477 } 484 }
478 catch (Exception e) 485 catch (Exception e)
479 { 486 {
480 LogException(e); 487 m_log.ErrorFormat(
488 "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}",
489 id, e.Message, e.StackTrace);
481 } 490 }
482 } 491 }
483 492
@@ -597,31 +606,59 @@ namespace Flotsam.RegionModules.AssetCache
597 606
598 try 607 try
599 { 608 {
600 if (!Directory.Exists(directory)) 609 try
601 { 610 {
602 Directory.CreateDirectory(directory); 611 if (!Directory.Exists(directory))
612 {
613 Directory.CreateDirectory(directory);
614 }
615
616 stream = File.Open(tempname, FileMode.Create);
617 BinaryFormatter bformatter = new BinaryFormatter();
618 bformatter.Serialize(stream, asset);
603 } 619 }
620 catch (IOException e)
621 {
622 m_log.ErrorFormat(
623 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.",
624 asset.ID, tempname, filename, directory, e.Message, e.StackTrace);
604 625
605 stream = File.Open(tempname, FileMode.Create); 626 return;
606 BinaryFormatter bformatter = new BinaryFormatter(); 627 }
607 bformatter.Serialize(stream, asset); 628 finally
608 stream.Close(); 629 {
609 630 if (stream != null)
610 // Now that it's written, rename it so that it can be found. 631 stream.Close();
611 File.Move(tempname, filename); 632 }
612 633
613 if (m_LogLevel >= 2) 634 try
614 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID); 635 {
615 } 636 // Now that it's written, rename it so that it can be found.
616 catch (Exception e) 637 //
617 { 638 // File.Copy(tempname, filename, true);
618 LogException(e); 639 // File.Delete(tempname);
640 //
641 // For a brief period, this was done as a separate copy and then temporary file delete operation to
642 // avoid an IOException caused by move if some competing thread had already written the file.
643 // However, this causes exceptions on Windows when other threads attempt to read a file
644 // which is still being copied. So instead, go back to moving the file and swallow any IOException.
645 //
646 // This situation occurs fairly rarely anyway. We assume in this that moves are atomic on the
647 // filesystem.
648 File.Move(tempname, filename);
649
650 if (m_LogLevel >= 2)
651 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID);
652 }
653 catch (IOException)
654 {
655 // If we see an IOException here it's likely that some other competing thread has written the
656 // cache file first, so ignore. Other IOException errors (e.g. filesystem full) should be
657 // signally by the earlier temporary file writing code.
658 }
619 } 659 }
620 finally 660 finally
621 { 661 {
622 if (stream != null)
623 stream.Close();
624
625 // Even if the write fails with an exception, we need to make sure 662 // Even if the write fails with an exception, we need to make sure
626 // that we release the lock on that file, otherwise it'll never get 663 // that we release the lock on that file, otherwise it'll never get
627 // cached 664 // cached
@@ -635,22 +672,9 @@ namespace Flotsam.RegionModules.AssetCache
635 waitEvent.Set(); 672 waitEvent.Set();
636 } 673 }
637#else 674#else
638 if (m_CurrentlyWriting.Contains(filename)) 675 m_CurrentlyWriting.Remove(filename);
639 {
640 m_CurrentlyWriting.Remove(filename);
641 }
642#endif 676#endif
643 } 677 }
644
645 }
646 }
647
648 private static void LogException(Exception e)
649 {
650 string[] text = e.ToString().Split(new char[] { '\n' });
651 foreach (string t in text)
652 {
653 m_log.ErrorFormat("[FLOTSAM ASSET CACHE]: {0} ", t);
654 } 678 }
655 } 679 }
656 680
@@ -706,8 +730,7 @@ namespace Flotsam.RegionModules.AssetCache
706 s.ForEachSOG(delegate(SceneObjectGroup e) 730 s.ForEachSOG(delegate(SceneObjectGroup e)
707 { 731 {
708 gatherer.GatherAssetUuids(e, assets); 732 gatherer.GatherAssetUuids(e, assets);
709 } 733 });
710 );
711 } 734 }
712 735
713 foreach (UUID assetID in assets.Keys) 736 foreach (UUID assetID in assets.Keys)
@@ -740,7 +763,9 @@ namespace Flotsam.RegionModules.AssetCache
740 } 763 }
741 catch (Exception e) 764 catch (Exception e)
742 { 765 {
743 LogException(e); 766 m_log.ErrorFormat(
767 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}",
768 dir, m_CacheDirectory, e.Message, e.StackTrace);
744 } 769 }
745 } 770 }
746 771
@@ -752,7 +777,9 @@ namespace Flotsam.RegionModules.AssetCache
752 } 777 }
753 catch (Exception e) 778 catch (Exception e)
754 { 779 {
755 LogException(e); 780 m_log.ErrorFormat(
781 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}",
782 file, m_CacheDirectory, e.Message, e.StackTrace);
756 } 783 }
757 } 784 }
758 } 785 }
@@ -778,7 +805,7 @@ namespace Flotsam.RegionModules.AssetCache
778 805
779 foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac")) 806 foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac"))
780 { 807 {
781 m_log.Info("[FLOTSAM ASSET CACHE]: Deep Scans were performed on the following regions:"); 808 m_log.Info("[FLOTSAM ASSET CACHE]: Deep scans have previously been performed on the following regions:");
782 809
783 string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac",""); 810 string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac","");
784 DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s); 811 DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s);
@@ -849,7 +876,6 @@ namespace Flotsam.RegionModules.AssetCache
849 Util.FireAndForget(delegate { 876 Util.FireAndForget(delegate {
850 int assetsCached = CacheScenes(); 877 int assetsCached = CacheScenes();
851 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached); 878 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached);
852
853 }); 879 });
854 880
855 break; 881 break;
@@ -904,7 +930,6 @@ namespace Flotsam.RegionModules.AssetCache
904 930
905 #region IAssetService Members 931 #region IAssetService Members
906 932
907
908 public AssetMetadata GetMetadata(string id) 933 public AssetMetadata GetMetadata(string id)
909 { 934 {
910 AssetBase asset = Get(id); 935 AssetBase asset = Get(id);
@@ -934,7 +959,6 @@ namespace Flotsam.RegionModules.AssetCache
934 Cache(asset); 959 Cache(asset);
935 960
936 return asset.ID; 961 return asset.ID;
937
938 } 962 }
939 963
940 public bool UpdateContent(string id, byte[] data) 964 public bool UpdateContent(string id, byte[] data)
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
index 63b0c31..2ff1920 100644
--- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
+++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
@@ -65,18 +65,18 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
65 config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true"); 65 config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true");
66 66
67 m_cache = new FlotsamAssetCache(); 67 m_cache = new FlotsamAssetCache();
68 m_scene = SceneSetupHelpers.SetupScene(); 68 m_scene = SceneHelpers.SetupScene();
69 SceneSetupHelpers.SetupSceneModules(m_scene, config, m_cache); 69 SceneHelpers.SetupSceneModules(m_scene, config, m_cache);
70 } 70 }
71 71
72 [Test] 72 [Test]
73 public void TestCacheAsset() 73 public void TestCacheAsset()
74 { 74 {
75 TestHelper.InMethod(); 75 TestHelpers.InMethod();
76// log4net.Config.XmlConfigurator.Configure(); 76// log4net.Config.XmlConfigurator.Configure();
77 77
78 AssetBase asset = AssetHelpers.CreateAsset(); 78 AssetBase asset = AssetHelpers.CreateAsset();
79 asset.ID = TestHelper.ParseTail(0x1).ToString(); 79 asset.ID = TestHelpers.ParseTail(0x1).ToString();
80 80
81 // Check we don't get anything before the asset is put in the cache 81 // Check we don't get anything before the asset is put in the cache
82 AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString()); 82 AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString());
@@ -93,11 +93,11 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
93 [Test] 93 [Test]
94 public void TestExpireAsset() 94 public void TestExpireAsset()
95 { 95 {
96 TestHelper.InMethod(); 96 TestHelpers.InMethod();
97// log4net.Config.XmlConfigurator.Configure(); 97// log4net.Config.XmlConfigurator.Configure();
98 98
99 AssetBase asset = AssetHelpers.CreateAsset(); 99 AssetBase asset = AssetHelpers.CreateAsset();
100 asset.ID = TestHelper.ParseTail(0x2).ToString(); 100 asset.ID = TestHelpers.ParseTail(0x2).ToString();
101 101
102 m_cache.Store(asset); 102 m_cache.Store(asset);
103 103
@@ -110,11 +110,11 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
110 [Test] 110 [Test]
111 public void TestClearCache() 111 public void TestClearCache()
112 { 112 {
113 TestHelper.InMethod(); 113 TestHelpers.InMethod();
114// log4net.Config.XmlConfigurator.Configure(); 114// log4net.Config.XmlConfigurator.Configure();
115 115
116 AssetBase asset = AssetHelpers.CreateAsset(); 116 AssetBase asset = AssetHelpers.CreateAsset();
117 asset.ID = TestHelper.ParseTail(0x2).ToString(); 117 asset.ID = TestHelpers.ParseTail(0x2).ToString();
118 118
119 m_cache.Store(asset); 119 m_cache.Store(asset);
120 120
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 47476a9..a130ed2 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -47,7 +47,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
47 { 47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 protected Scene m_scene = null; 50 private Scene m_scene;
51 private IDialogModule m_dialogModule;
51 52
52 public string Name { get { return "Attachments Module"; } } 53 public string Name { get { return "Attachments Module"; } }
53 public Type ReplaceableInterface { get { return null; } } 54 public Type ReplaceableInterface { get { return null; } }
@@ -57,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
57 public void AddRegion(Scene scene) 58 public void AddRegion(Scene scene)
58 { 59 {
59 m_scene = scene; 60 m_scene = scene;
61 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
60 m_scene.RegisterModuleInterface<IAttachmentsModule>(this); 62 m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
61 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 63 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
62 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI 64 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI
@@ -81,7 +83,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
81 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory; 83 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory;
82 client.OnObjectAttach += AttachObject; 84 client.OnObjectAttach += AttachObject;
83 client.OnObjectDetach += DetachObject; 85 client.OnObjectDetach += DetachObject;
84 client.OnDetachAttachmentIntoInv += ShowDetachInUserInventory; 86 client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
87 client.OnObjectDrop += DetachSingleAttachmentToGround;
85 } 88 }
86 89
87 public void UnsubscribeFromClientEvents(IClientAPI client) 90 public void UnsubscribeFromClientEvents(IClientAPI client)
@@ -90,7 +93,83 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
90 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory; 93 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory;
91 client.OnObjectAttach -= AttachObject; 94 client.OnObjectAttach -= AttachObject;
92 client.OnObjectDetach -= DetachObject; 95 client.OnObjectDetach -= DetachObject;
93 client.OnDetachAttachmentIntoInv -= ShowDetachInUserInventory; 96 client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv;
97 client.OnObjectDrop -= DetachSingleAttachmentToGround;
98 }
99
100 /// <summary>
101 /// RezAttachments. This should only be called upon login on the first region.
102 /// Attachment rezzings on crossings and TPs are done in a different way.
103 /// </summary>
104 public void RezAttachments(IScenePresence sp)
105 {
106 if (null == sp.Appearance)
107 {
108 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
109 return;
110 }
111
112 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
113 foreach (AvatarAttachment attach in attachments)
114 {
115 uint p = (uint)attach.AttachPoint;
116
117// m_log.DebugFormat(
118// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}",
119// attach.ItemID, attach.AssetID, p, sp.Name, m_scene.RegionInfo.RegionName);
120
121 // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down
122 // But they're not used anyway, the item is being looked up for now, so let's proceed.
123 //if (UUID.Zero == assetID)
124 //{
125 // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID);
126 // continue;
127 //}
128
129 try
130 {
131 // If we're an NPC then skip all the item checks and manipulations since we don't have an
132 // inventory right now.
133 if (sp.PresenceType == PresenceType.Npc)
134 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null);
135 else
136 RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p);
137 }
138 catch (Exception e)
139 {
140 m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace);
141 }
142 }
143 }
144
145 public void SaveChangedAttachments(IScenePresence sp)
146 {
147// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
148
149 foreach (SceneObjectGroup grp in sp.GetAttachments())
150 {
151// if (grp.HasGroupChanged) // Resizer scripts?
152// {
153 grp.IsAttachment = false;
154 grp.AbsolutePosition = grp.RootPart.AttachedPos;
155 UpdateKnownItem(sp.ControllingClient, grp);
156 grp.IsAttachment = true;
157// }
158 }
159 }
160
161 public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
162 {
163// m_log.DebugFormat(
164// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
165// m_scene.RegionInfo.RegionName, sp.Name, silent);
166
167 foreach (SceneObjectGroup sop in sp.GetAttachments())
168 {
169 sop.Scene.DeleteSceneObject(sop, silent);
170 }
171
172 sp.ClearAttachments();
94 } 173 }
95 174
96 /// <summary> 175 /// <summary>
@@ -102,10 +181,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
102 /// <param name="silent"></param> 181 /// <param name="silent"></param>
103 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) 182 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
104 { 183 {
105 m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); 184// m_log.DebugFormat(
185// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
186// objectLocalID, remoteClient.Name, AttachmentPt, silent);
106 187
107 try 188 try
108 { 189 {
190 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
191
192 if (sp == null)
193 {
194 m_log.ErrorFormat(
195 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
196 return;
197 }
198
109 // If we can't take it, we can't attach it! 199 // If we can't take it, we can't attach it!
110 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); 200 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
111 if (part == null) 201 if (part == null)
@@ -131,12 +221,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
131 AttachmentPt &= 0x7f; 221 AttachmentPt &= 0x7f;
132 222
133 // Calls attach with a Zero position 223 // Calls attach with a Zero position
134 if (AttachObject(remoteClient, part.ParentGroup, AttachmentPt, false)) 224 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
135 { 225 {
136 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); 226 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
137 227
138 // Save avatar attachment information 228 // Save avatar attachment information
139 m_log.Info( 229 m_log.Debug(
140 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId 230 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
141 + ", AttachmentPoint: " + AttachmentPt); 231 + ", AttachmentPoint: " + AttachmentPt);
142 232
@@ -144,74 +234,103 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
144 } 234 }
145 catch (Exception e) 235 catch (Exception e)
146 { 236 {
147 m_log.DebugFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}", e); 237 m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
148 } 238 }
149 } 239 }
150 240
151 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) 241 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent)
152 { 242 {
153 Vector3 attachPos = group.AbsolutePosition; 243 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
154
155 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
156 // be removed when that functionality is implemented in opensim
157 AttachmentPt &= 0x7f;
158
159 // If the attachment point isn't the same as the one previously used
160 // set it's offset position = 0 so that it appears on the attachment point
161 // and not in a weird location somewhere unknown.
162 if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
163 {
164 attachPos = Vector3.Zero;
165 }
166
167 // AttachmentPt 0 means the client chose to 'wear' the attachment.
168 if (AttachmentPt == 0)
169 {
170 // Check object for stored attachment point
171 AttachmentPt = (uint)group.GetAttachmentPoint();
172 }
173 244
174 // if we still didn't find a suitable attachment point....... 245 if (sp == null)
175 if (AttachmentPt == 0)
176 { 246 {
177 // Stick it on left hand with Zero Offset from the attachment point. 247 m_log.ErrorFormat(
178 AttachmentPt = (uint)AttachmentPoint.LeftHand; 248 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
179 attachPos = Vector3.Zero; 249 return false;
180 } 250 }
181 251
182 group.SetAttachmentPoint((byte)AttachmentPt); 252 return AttachObject(sp, group, AttachmentPt, silent);
183 group.AbsolutePosition = attachPos; 253 }
184 254
185 // Remove any previous attachments 255 private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
186 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); 256 {
187 UUID itemID = UUID.Zero; 257 lock (sp.AttachmentsSyncLock)
188 if (sp != null)
189 { 258 {
190 foreach (SceneObjectGroup grp in sp.Attachments) 259// m_log.DebugFormat(
260// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
261// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
262
263 if (sp.GetAttachments(attachmentPt).Contains(group))
264 {
265 // m_log.WarnFormat(
266 // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
267 // group.Name, group.LocalId, sp.Name, AttachmentPt);
268
269 return false;
270 }
271
272 Vector3 attachPos = group.AbsolutePosition;
273
274 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
275 // be removed when that functionality is implemented in opensim
276 attachmentPt &= 0x7f;
277
278 // If the attachment point isn't the same as the one previously used
279 // set it's offset position = 0 so that it appears on the attachment point
280 // and not in a weird location somewhere unknown.
281 if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
282 {
283 attachPos = Vector3.Zero;
284 }
285
286 // AttachmentPt 0 means the client chose to 'wear' the attachment.
287 if (attachmentPt == 0)
288 {
289 // Check object for stored attachment point
290 attachmentPt = group.AttachmentPoint;
291 }
292
293 // if we still didn't find a suitable attachment point.......
294 if (attachmentPt == 0)
191 { 295 {
192 if (grp.GetAttachmentPoint() == (byte)AttachmentPt) 296 // Stick it on left hand with Zero Offset from the attachment point.
297 attachmentPt = (uint)AttachmentPoint.LeftHand;
298 attachPos = Vector3.Zero;
299 }
300
301 group.AttachmentPoint = attachmentPt;
302 group.AbsolutePosition = attachPos;
303
304 // We also don't want to do any of the inventory operations for an NPC.
305 if (sp.PresenceType != PresenceType.Npc)
306 {
307 // Remove any previous attachments
308 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
309
310 // At the moment we can only deal with a single attachment
311 if (attachments.Count != 0)
193 { 312 {
194 itemID = grp.GetFromItemID(); 313 UUID oldAttachmentItemID = attachments[0].GetFromItemID();
195 break; 314
315 if (oldAttachmentItemID != UUID.Zero)
316 DetachSingleAttachmentToInv(oldAttachmentItemID, sp);
317 else
318 m_log.WarnFormat(
319 "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
320 attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
196 } 321 }
322
323 // Add the new attachment to inventory if we don't already have it.
324 UUID newAttachmentItemID = group.GetFromItemID();
325 if (newAttachmentItemID == UUID.Zero)
326 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID;
327
328 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
197 } 329 }
198 if (itemID != UUID.Zero) 330
199 DetachSingleAttachmentToInv(itemID, remoteClient); 331 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
200 } 332 }
201 333
202 if (group.GetFromItemID() == UUID.Zero)
203 {
204 m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID);
205 }
206 else
207 {
208 itemID = group.GetFromItemID();
209 }
210
211 ShowAttachInUserInventory(remoteClient, AttachmentPt, itemID, group);
212
213 AttachToAgent(sp, group, AttachmentPt, attachPos, silent);
214
215 return true; 334 return true;
216 } 335 }
217 336
@@ -220,84 +339,159 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
220 RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, 339 RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
221 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) 340 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects)
222 { 341 {
223 foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects) 342 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
343
344 if (sp == null)
224 { 345 {
225 RezSingleAttachmentFromInventory(remoteClient, obj.ItemID, obj.AttachmentPt); 346 m_log.ErrorFormat(
347 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()",
348 remoteClient.Name, remoteClient.AgentId);
349 return;
350 }
351
352 lock (sp.AttachmentsSyncLock)
353 {
354// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name);
355
356 foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
357 {
358 RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt);
359 }
226 } 360 }
227 } 361 }
228 362
229 public UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) 363 public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
230 { 364 {
231 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true); 365 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null);
232 } 366 }
233 367
234 public UUID RezSingleAttachmentFromInventory( 368 public ISceneEntity RezSingleAttachmentFromInventory(
235 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) 369 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
236 { 370 {
237 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); 371 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
372
373 if (sp == null)
374 {
375 m_log.ErrorFormat(
376 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()",
377 remoteClient.Name, remoteClient.AgentId);
378 return null;
379 }
380
381 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt);
238 } 382 }
239 383
240 public UUID RezSingleAttachmentFromInventory( 384 public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt)
241 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
242 { 385 {
386// m_log.DebugFormat(
387// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
388// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
389
243 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 390 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
244 // be removed when that functionality is implemented in opensim 391 // be removed when that functionality is implemented in opensim
245 AttachmentPt &= 0x7f; 392 AttachmentPt &= 0x7f;
246 393
247 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(remoteClient, itemID, AttachmentPt, doc); 394 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
395 // This often happens during login - not sure the exact reason.
396 // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the
397 // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login
398 // before anything has actually been attached.
399 bool alreadyOn = false;
400 List<SceneObjectGroup> existingAttachments = sp.GetAttachments();
401 foreach (SceneObjectGroup so in existingAttachments)
402 {
403 if (so.GetFromItemID() == itemID)
404 {
405 alreadyOn = true;
406 break;
407 }
408 }
248 409
249 if (updateInventoryStatus) 410// if (sp.Appearance.GetAttachmentForItem(itemID) != null)
411 if (alreadyOn)
250 { 412 {
251 if (att == null) 413// m_log.WarnFormat(
252 ShowDetachInUserInventory(itemID, remoteClient); 414// "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn",
253 else 415// sp.Name, itemID, AttachmentPt);
254 ShowAttachInUserInventory(att, remoteClient, itemID, AttachmentPt); 416
417 return null;
255 } 418 }
256 419
257 if (null == att) 420 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, null);
258 return UUID.Zero; 421
259 else 422 if (att == null)
260 return att.UUID; 423 DetachSingleAttachmentToInv(itemID, sp.ControllingClient);
424
425 return att;
261 } 426 }
262 427
263 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 428 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
264 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, XmlDocument doc) 429 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
265 { 430 {
266 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 431 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
267 if (invAccess != null) 432 if (invAccess != null)
268 { 433 {
269 SceneObjectGroup objatt = invAccess.RezObject(remoteClient, 434 lock (sp.AttachmentsSyncLock)
270 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
271 false, false, remoteClient.AgentId, true);
272
273// m_log.DebugFormat(
274// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
275// objatt.Name, remoteClient.Name, AttachmentPt);
276
277 if (objatt != null)
278 { 435 {
279 // Loading the inventory from XML will have set this, but 436 SceneObjectGroup objatt;
280 // there is no way the object could have changed yet, 437
281 // since scripts aren't running yet. So, clear it here. 438 if (itemID != UUID.Zero)
282 objatt.HasGroupChanged = false; 439 objatt = invAccess.RezObject(sp.ControllingClient,
283 bool tainted = false; 440 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
284 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) 441 false, false, sp.UUID, true);
285 tainted = true; 442 else
286 443 objatt = invAccess.RezObject(sp.ControllingClient,
287 // This will throw if the attachment fails 444 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
288 try 445 false, false, sp.UUID, true);
446
447 // m_log.DebugFormat(
448 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
449 // objatt.Name, remoteClient.Name, AttachmentPt);
450
451 if (objatt != null)
289 { 452 {
290 AttachObject(remoteClient, objatt, AttachmentPt, false); 453 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
454 objatt.HasGroupChanged = false;
455 bool tainted = false;
456 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
457 tainted = true;
458
459 // This will throw if the attachment fails
460 try
461 {
462 AttachObject(sp, objatt, attachmentPt, false);
463 }
464 catch (Exception e)
465 {
466 m_log.ErrorFormat(
467 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
468 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
469
470 // Make sure the object doesn't stick around and bail
471 sp.RemoveAttachment(objatt);
472 m_scene.DeleteSceneObject(objatt, false);
473 return null;
474 }
475
476 if (tainted)
477 objatt.HasGroupChanged = true;
478
479 // Fire after attach, so we don't get messy perms dialogs
480 // 4 == AttachedRez
481 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
482 objatt.ResumeScripts();
483
484 // Do this last so that event listeners have access to all the effects of the attachment
485 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
486
487 return objatt;
291 } 488 }
292 catch 489 else
293 { 490 {
294 // Make sure the object doesn't stick around and bail 491 m_log.WarnFormat(
295 m_scene.DeleteSceneObject(objatt, false); 492 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
296 return null; 493 itemID, sp.Name, attachmentPt);
297 } 494 }
298
299 if (tainted)
300 objatt.HasGroupChanged = true;
301 495
302 if (doc != null) 496 if (doc != null)
303 { 497 {
@@ -311,67 +505,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
311 objatt.ResumeScripts(); 505 objatt.ResumeScripts();
312 506
313 // Do this last so that event listeners have access to all the effects of the attachment 507 // Do this last so that event listeners have access to all the effects of the attachment
314 //m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); 508 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
315 } 509 }
316 else
317 {
318 m_log.WarnFormat(
319 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
320 itemID, remoteClient.Name, AttachmentPt);
321 }
322
323 return objatt;
324 } 510 }
325 511
326 return null; 512 return null;
327 } 513 }
328
329 /// <summary>
330 /// Update the user inventory to the attachment of an item
331 /// </summary>
332 /// <param name="att"></param>
333 /// <param name="remoteClient"></param>
334 /// <param name="itemID"></param>
335 /// <param name="AttachmentPt"></param>
336 /// <returns></returns>
337 protected UUID ShowAttachInUserInventory(
338 SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
339 {
340// m_log.DebugFormat(
341// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
342// remoteClient.Name, att.Name, itemID);
343
344 if (!att.IsDeleted)
345 AttachmentPt = att.RootPart.AttachmentPoint;
346
347 ScenePresence presence;
348 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
349 {
350 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
351 if (m_scene.InventoryService != null)
352 item = m_scene.InventoryService.GetItem(item);
353
354 bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
355 if (changed && m_scene.AvatarFactory != null)
356 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
357 }
358
359 return att.UUID;
360 }
361 514
362 /// <summary> 515 /// <summary>
363 /// Update the user inventory to reflect an attachment 516 /// Update the user inventory to reflect an attachment
364 /// </summary> 517 /// </summary>
365 /// <param name="remoteClient"></param> 518 /// <param name="sp"></param>
366 /// <param name="AttachmentPt"></param> 519 /// <param name="AttachmentPt"></param>
367 /// <param name="itemID"></param> 520 /// <param name="itemID"></param>
368 /// <param name="att"></param> 521 /// <param name="att"></param>
369 protected void ShowAttachInUserInventory( 522 private void ShowAttachInUserInventory(
370 IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 523 IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
371 { 524 {
372// m_log.DebugFormat( 525// m_log.DebugFormat(
373// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 526// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
374// att.Name, remoteClient.Name, AttachmentPt, itemID); 527// att.Name, sp.Name, AttachmentPt, itemID);
375 528
376 if (UUID.Zero == itemID) 529 if (UUID.Zero == itemID)
377 { 530 {
@@ -390,88 +543,129 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
390 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!"); 543 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
391 return; 544 return;
392 } 545 }
546 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
393 547
394 ScenePresence presence; 548
395 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 549
396 { 550
397 // XXYY!! 551
398 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 552
399 if (item == null) 553 item = m_scene.InventoryService.GetItem(item);
400 m_log.Error("[ATTACHMENT]: item == null"); 554 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
401 if (m_scene == null) 555 if (changed && m_scene.AvatarFactory != null)
402 m_log.Error("[ATTACHMENT]: m_scene == null"); 556 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
403 if (m_scene.InventoryService == null)
404 m_log.Error("[ATTACHMENT]: m_scene.InventoryService == null");
405 item = m_scene.InventoryService.GetItem(item);
406 bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
407 if (changed && m_scene.AvatarFactory != null)
408 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
409 }
410 } 557 }
411 558
412 public void DetachObject(uint objectLocalID, IClientAPI remoteClient) 559 public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
413 { 560 {
561// m_log.DebugFormat(
562// "[ATTACHMENTS MODULE]: DetachObject() for object {0} on {1}", objectLocalID, remoteClient.Name);
563
414 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); 564 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
415 if (group != null) 565 if (group != null)
416 { 566 {
417 //group.DetachToGround(); 567 DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient);
418 ShowDetachInUserInventory(group.GetFromItemID(), remoteClient);
419 } 568 }
420 } 569 }
421 570
422 public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient) 571 public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
423 { 572 {
424 ScenePresence presence; 573 ScenePresence presence;
425 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 574 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
426 { 575 {
427 // Save avatar attachment information 576 lock (presence.AttachmentsSyncLock)
428 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); 577 {
578 // Save avatar attachment information
579 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
429 580
430 bool changed = presence.Appearance.DetachAttachment(itemID); 581 bool changed = presence.Appearance.DetachAttachment(itemID);
431 if (changed && m_scene.AvatarFactory != null) 582 if (changed && m_scene.AvatarFactory != null)
432 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 583 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
584
585 DetachSingleAttachmentToInv(itemID, presence);
586 }
433 } 587 }
434
435 DetachSingleAttachmentToInv(itemID, remoteClient);
436 } 588 }
437 589
438 public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient) 590 public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient)
439 { 591 {
440 SceneObjectPart part = m_scene.GetSceneObjectPart(itemID); 592// m_log.DebugFormat(
441 if (part == null || part.ParentGroup == null) 593// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
594// remoteClient.Name, soLocalId);
595
596 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
597
598 if (so == null)
442 return; 599 return;
443 600
444 if (part.ParentGroup.RootPart.AttachedAvatar != remoteClient.AgentId) 601 if (so.AttachedAvatar != remoteClient.AgentId)
445 return; 602 return;
446 603
447 UUID inventoryID = part.ParentGroup.GetFromItemID(); 604 UUID inventoryID = so.GetFromItemID();
605
606// m_log.DebugFormat(
607// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
608// so.Name, so.LocalId, inventoryID);
448 609
449 ScenePresence presence; 610 ScenePresence presence;
450 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 611 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
451 { 612 {
452 if (!m_scene.Permissions.CanRezObject( 613 lock (presence.AttachmentsSyncLock)
453 part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) 614 {
454 return; 615 if (!m_scene.Permissions.CanRezObject(
616 so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
617 return;
455 618
456 bool changed = presence.Appearance.DetachAttachment(itemID); 619 bool changed = presence.Appearance.DetachAttachment(inventoryID);
457 if (changed && m_scene.AvatarFactory != null) 620 if (changed && m_scene.AvatarFactory != null)
458 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 621 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
459 622
460 part.ParentGroup.DetachToGround(); 623 presence.RemoveAttachment(so);
624 DetachSceneObjectToGround(so, presence);
461 625
462 List<UUID> uuids = new List<UUID>(); 626 List<UUID> uuids = new List<UUID>();
463 uuids.Add(inventoryID); 627 uuids.Add(inventoryID);
464 m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids); 628 m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids);
465 remoteClient.SendRemoveInventoryItem(inventoryID); 629 remoteClient.SendRemoveInventoryItem(inventoryID);
630 }
631
632 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
466 } 633 }
634 }
467 635
468 m_scene.EventManager.TriggerOnAttach(part.ParentGroup.LocalId, itemID, UUID.Zero); 636 /// <summary>
637 /// Detach the given scene object to the ground.
638 /// </summary>
639 /// <remarks>
640 /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc.
641 /// </remarks>
642 /// <param name="so">The scene object to detach.</param>
643 /// <param name="sp">The scene presence from which the scene object is being detached.</param>
644 private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp)
645 {
646 SceneObjectPart rootPart = so.RootPart;
647
648 rootPart.FromItemID = UUID.Zero;
649 so.AbsolutePosition = sp.AbsolutePosition;
650 so.AttachedAvatar = UUID.Zero;
651 rootPart.SetParentLocalId(0);
652 so.ClearPartAttachmentData();
653 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
654 so.HasGroupChanged = true;
655 rootPart.Rezzed = DateTime.Now;
656 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
657 so.AttachToBackup();
658 m_scene.EventManager.TriggerParcelPrimCountTainted();
659 rootPart.ScheduleFullUpdate();
660 rootPart.ClearUndoState();
469 } 661 }
470 662
471 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. 663 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
472 // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? 664 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
473 protected void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) 665 private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
474 { 666 {
667// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
668
475 if (itemID == UUID.Zero) // If this happened, someone made a mistake.... 669 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
476 return; 670 return;
477 671
@@ -480,60 +674,70 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
480 EntityBase[] detachEntities = m_scene.GetEntities(); 674 EntityBase[] detachEntities = m_scene.GetEntities();
481 SceneObjectGroup group; 675 SceneObjectGroup group;
482 676
483 foreach (EntityBase entity in detachEntities) 677 lock (sp.AttachmentsSyncLock)
484 { 678 {
485 if (entity is SceneObjectGroup) 679 foreach (EntityBase entity in detachEntities)
486 { 680 {
487 group = (SceneObjectGroup)entity; 681 if (entity is SceneObjectGroup)
488 if (group.GetFromItemID() == itemID)
489 { 682 {
490 m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); 683 group = (SceneObjectGroup)entity; if (group.GetFromItemID() == itemID) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
491 // CM / XMREngine!!!! Needed to conclude attach event 684 // CM / XMREngine!!!! Needed to conclude attach event
492 //SceneObjectSerializer.ToOriginalXmlFormat(group); 685 //SceneObjectSerializer.ToOriginalXmlFormat(group);
493 group.DetachToInventoryPrep(); 686 group.DetachToInventoryPrep();
494 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); 687 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
495 688
496 // If an item contains scripts, it's always changed. 689 // Prepare sog for storage
497 // This ensures script state is saved on detach 690 group.AttachedAvatar = UUID.Zero;
498 foreach (SceneObjectPart p in group.Parts) 691 group.RootPart.SetParentLocalId(0);
499 if (p.Inventory.ContainsScripts()) 692 group.IsAttachment = false;
500 group.HasGroupChanged = true; 693 group.AbsolutePosition = group.RootPart.AttachedPos;
501 694
502 UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); 695 UpdateKnownItem(sp.ControllingClient, group);
503 m_scene.DeleteSceneObject(group, false); 696 m_scene.DeleteSceneObject(group, false);
504 return; 697
698 return;
699 }
505 } 700 }
506 } 701 }
507 } 702 }
508 } 703 }
509 704
705 public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos)
706 {
707 // First we save the
708 // attachment point information, then we update the relative
709 // positioning. Then we have to mark the object as NOT an
710 // attachment. This is necessary in order to correctly save
711 // and retrieve GroupPosition information for the attachment.
712 // Finally, we restore the object's attachment status.
713 uint attachmentPoint = sog.AttachmentPoint;
714 sog.UpdateGroupPosition(pos);
715 sog.IsAttachment = false;
716 sog.AbsolutePosition = sog.RootPart.AttachedPos;
717 sog.AttachmentPoint = attachmentPoint;
718 sog.HasGroupChanged = true;
719 }
720
510 /// <summary> 721 /// <summary>
511 /// Update the attachment asset for the new sog details if they have changed. 722 /// Update the attachment asset for the new sog details if they have changed.
512 /// </summary> 723 /// </summary>
513 /// 724 /// <remarks>
514 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, 725 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects,
515 /// these details are not stored on the region. 726 /// these details are not stored on the region.
516 /// 727 /// </remarks>
517 /// <param name="remoteClient"></param> 728 /// <param name="remoteClient"></param>
518 /// <param name="grp"></param> 729 /// <param name="grp"></param>
519 /// <param name="itemID"></param> 730 private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp)
520 /// <param name="agentID"></param>
521 public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
522 { 731 {
523 if (grp != null) 732 if (grp.HasGroupChanged || grp.ContainsScripts())
524 { 733 {
525 if (!grp.HasGroupChanged)
526 {
527 m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID);
528 return;
529 }
530
531 m_log.DebugFormat( 734 m_log.DebugFormat(
532 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 735 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
533 grp.UUID, grp.GetAttachmentPoint()); 736 grp.UUID, grp.AttachmentPoint);
534 737
535 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 738 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
536 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 739
740 InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), remoteClient.AgentId);
537 item = m_scene.InventoryService.GetItem(item); 741 item = m_scene.InventoryService.GetItem(item);
538 742
539 if (item != null) 743 if (item != null)
@@ -559,25 +763,32 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
559 remoteClient.SendInventoryItemCreateUpdate(item, 0); 763 remoteClient.SendInventoryItemCreateUpdate(item, 0);
560 } 764 }
561 } 765 }
766 else
767 {
768 m_log.DebugFormat(
769 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
770 grp.UUID, grp.AttachmentPoint);
771 }
562 } 772 }
563 773
564 /// <summary> 774 /// <summary>
565 /// Attach this scene object to the given avatar. 775 /// Attach this scene object to the given avatar.
566 /// </summary> 776 /// </summary>
567 /// 777 /// <remarks>
568 /// This isn't publicly available since attachments should always perform the corresponding inventory 778 /// This isn't publicly available since attachments should always perform the corresponding inventory
569 /// operation (to show the attach in user inventory and update the asset with positional information). 779 /// operation (to show the attach in user inventory and update the asset with positional information).
570 /// 780 /// </remarks>
571 /// <param name="sp"></param> 781 /// <param name="sp"></param>
572 /// <param name="so"></param> 782 /// <param name="so"></param>
573 /// <param name="attachmentpoint"></param> 783 /// <param name="attachmentpoint"></param>
574 /// <param name="attachOffset"></param> 784 /// <param name="attachOffset"></param>
575 /// <param name="silent"></param> 785 /// <param name="silent"></param>
576 protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) 786 private void AttachToAgent(
787 IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
577 { 788 {
578 789// m_log.DebugFormat(
579 m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name, 790// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
580 attachmentpoint, attachOffset, so.RootPart.AttachedPos); 791// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
581 792
582 so.DetachFromBackup(); 793 so.DetachFromBackup();
583 794
@@ -585,12 +796,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
585 m_scene.DeleteFromStorage(so.UUID); 796 m_scene.DeleteFromStorage(so.UUID);
586 m_scene.EventManager.TriggerParcelPrimCountTainted(); 797 m_scene.EventManager.TriggerParcelPrimCountTainted();
587 798
588 so.RootPart.AttachedAvatar = avatar.UUID; 799 so.AttachedAvatar = avatar.UUID;
589
590 //Anakin Lohner bug #3839
591 SceneObjectPart[] parts = so.Parts;
592 for (int i = 0; i < parts.Length; i++)
593 parts[i].AttachedAvatar = avatar.UUID;
594 800
595 if (so.RootPart.PhysActor != null) 801 if (so.RootPart.PhysActor != null)
596 { 802 {
@@ -600,10 +806,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
600 806
601 so.AbsolutePosition = attachOffset; 807 so.AbsolutePosition = attachOffset;
602 so.RootPart.AttachedPos = attachOffset; 808 so.RootPart.AttachedPos = attachOffset;
603 so.RootPart.IsAttachment = true; 809 so.IsAttachment = true;
604
605 so.RootPart.SetParentLocalId(avatar.LocalId); 810 so.RootPart.SetParentLocalId(avatar.LocalId);
606 so.SetAttachmentPoint(Convert.ToByte(attachmentpoint)); 811 so.AttachmentPoint = attachmentpoint;
607 812
608 avatar.AddAttachment(so); 813 avatar.AddAttachment(so);
609 814
@@ -617,5 +822,99 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
617 // it get cleaned up 822 // it get cleaned up
618 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); 823 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
619 } 824 }
825
826 /// <summary>
827 /// Add a scene object as a new attachment in the user inventory.
828 /// </summary>
829 /// <param name="remoteClient"></param>
830 /// <param name="grp"></param>
831 /// <returns>The user inventory item created that holds the attachment.</returns>
832 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp)
833 {
834// m_log.DebugFormat(
835// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
836// grp.Name, grp.LocalId, remoteClient.Name);
837 uint regionSize = Constants.RegionSize; //Avoid VS error "The operation overflows at compile time in checked mode"
838 Vector3 inventoryStoredPosition = new Vector3
839 (((grp.AbsolutePosition.X > (int)Constants.RegionSize)
840 ? regionSize - 6
841 : grp.AbsolutePosition.X)
842 ,
843 (grp.AbsolutePosition.Y > (int)Constants.RegionSize)
844 ? regionSize - 6
845 : grp.AbsolutePosition.Y,
846 grp.AbsolutePosition.Z);
847
848 Vector3 originalPosition = grp.AbsolutePosition;
849
850 grp.AbsolutePosition = inventoryStoredPosition;
851
852 // If we're being called from a script, then trying to serialize that same script's state will not complete
853 // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
854 // the client/server crashes rather than logging out normally, the attachment's scripts will resume
855 // without state on relog. Arguably, this is what we want anyway.
856 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false);
857
858 grp.AbsolutePosition = originalPosition;
859
860 AssetBase asset = m_scene.CreateAsset(
861 grp.GetPartName(grp.LocalId),
862 grp.GetPartDescription(grp.LocalId),
863 (sbyte)AssetType.Object,
864 Utils.StringToBytes(sceneObjectXml),
865 remoteClient.AgentId);
866
867 m_scene.AssetService.Store(asset);
868
869 InventoryItemBase item = new InventoryItemBase();
870 item.CreatorId = grp.RootPart.CreatorID.ToString();
871 item.CreatorData = grp.RootPart.CreatorData;
872 item.Owner = remoteClient.AgentId;
873 item.ID = UUID.Random();
874 item.AssetID = asset.FullID;
875 item.Description = asset.Description;
876 item.Name = asset.Name;
877 item.AssetType = asset.Type;
878 item.InvType = (int)InventoryType.Object;
879
880 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object);
881 if (folder != null)
882 item.Folder = folder.ID;
883 else // oopsies
884 item.Folder = UUID.Zero;
885
886 if ((remoteClient.AgentId != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
887 {
888 item.BasePermissions = grp.RootPart.NextOwnerMask;
889 item.CurrentPermissions = grp.RootPart.NextOwnerMask;
890 item.NextPermissions = grp.RootPart.NextOwnerMask;
891 item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
892 item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
893 }
894 else
895 {
896 item.BasePermissions = grp.RootPart.BaseMask;
897 item.CurrentPermissions = grp.RootPart.OwnerMask;
898 item.NextPermissions = grp.RootPart.NextOwnerMask;
899 item.EveryOnePermissions = grp.RootPart.EveryoneMask;
900 item.GroupPermissions = grp.RootPart.GroupMask;
901 }
902 item.CreationDate = Util.UnixTimeSinceEpoch();
903
904 // sets itemID so client can show item as 'attached' in inventory
905 grp.SetFromItemID(item.ID);
906
907 if (m_scene.AddInventoryItem(item))
908 {
909 remoteClient.SendInventoryItemCreateUpdate(item, 0);
910 }
911 else
912 {
913 if (m_dialogModule != null)
914 m_dialogModule.SendAlertToUser(remoteClient, "Operation failed");
915 }
916
917 return item;
918 }
620 } 919 }
621} 920} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
new file mode 100644
index 0000000..ff3358f
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -0,0 +1,319 @@
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 OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Region.CoreModules.Avatar.Attachments;
41using OpenSim.Region.CoreModules.Framework.InventoryAccess;
42using OpenSim.Region.CoreModules.World.Serialiser;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48
49namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
50{
51 /// <summary>
52 /// Attachment tests
53 /// </summary>
54 [TestFixture]
55 public class AttachmentsModuleTests
56 {
57 private Scene scene;
58 private AttachmentsModule m_attMod;
59 private ScenePresence m_presence;
60
61 [TestFixtureSetUp]
62 public void FixtureInit()
63 {
64 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
65 Util.FireAndForgetMethod = FireAndForgetMethod.None;
66 }
67
68 [SetUp]
69 public void Init()
70 {
71 IConfigSource config = new IniConfigSource();
72 config.AddConfig("Modules");
73 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
74
75 scene = SceneHelpers.SetupScene();
76 m_attMod = new AttachmentsModule();
77 SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
78 }
79
80 [TestFixtureTearDown]
81 public void TearDown()
82 {
83 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
84 // threads. Possibly, later tests should be rewritten not to worry about such things.
85 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
86 }
87
88 /// <summary>
89 /// Add the standard presence for a test.
90 /// </summary>
91 private void AddPresence()
92 {
93 UUID userId = TestHelpers.ParseTail(0x1);
94 UserAccountHelpers.CreateUserWithInventory(scene, userId);
95 m_presence = SceneHelpers.AddScenePresence(scene, userId);
96 }
97
98 [Test]
99 public void TestAddAttachmentFromGround()
100 {
101 TestHelpers.InMethod();
102// log4net.Config.XmlConfigurator.Configure();
103
104 AddPresence();
105 string attName = "att";
106
107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
108
109 m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false);
110
111 // Check status on scene presence
112 Assert.That(m_presence.HasAttachments(), Is.True);
113 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
114 Assert.That(attachments.Count, Is.EqualTo(1));
115 SceneObjectGroup attSo = attachments[0];
116 Assert.That(attSo.Name, Is.EqualTo(attName));
117 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
118 Assert.That(attSo.IsAttachment);
119 Assert.That(attSo.UsesPhysics, Is.False);
120 Assert.That(attSo.IsTemporary, Is.False);
121
122 // Check item status
123 Assert.That(m_presence.Appearance.GetAttachpoint(
124 attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest));
125 }
126
127 [Test]
128 public void TestAddAttachmentFromInventory()
129 {
130 TestHelpers.InMethod();
131// log4net.Config.XmlConfigurator.Configure();
132
133 AddPresence();
134
135 UUID attItemId = TestHelpers.ParseTail(0x2);
136 UUID attAssetId = TestHelpers.ParseTail(0x3);
137 string attName = "att";
138
139 UserInventoryHelpers.CreateInventoryItem(
140 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
141
142 m_attMod.RezSingleAttachmentFromInventory(
143 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
144
145 // Check scene presence status
146 Assert.That(m_presence.HasAttachments(), Is.True);
147 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
148 Assert.That(attachments.Count, Is.EqualTo(1));
149 SceneObjectGroup attSo = attachments[0];
150 Assert.That(attSo.Name, Is.EqualTo(attName));
151 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
152 Assert.That(attSo.IsAttachment);
153 Assert.That(attSo.UsesPhysics, Is.False);
154 Assert.That(attSo.IsTemporary, Is.False);
155
156 // Check appearance status
157 Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1));
158 Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
159 }
160
161 [Test]
162 public void TestDetachAttachmentToGround()
163 {
164 TestHelpers.InMethod();
165// log4net.Config.XmlConfigurator.Configure();
166
167 AddPresence();
168
169 UUID attItemId = TestHelpers.ParseTail(0x2);
170 UUID attAssetId = TestHelpers.ParseTail(0x3);
171 string attName = "att";
172
173 UserInventoryHelpers.CreateInventoryItem(
174 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
175
176 ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
177 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
178 m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient);
179
180 // Check scene presence status
181 Assert.That(m_presence.HasAttachments(), Is.False);
182 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
183 Assert.That(attachments.Count, Is.EqualTo(0));
184
185 // Check appearance status
186 Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0));
187
188 // Check item status
189 Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null);
190
191 // Check object in scene
192 Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
193 }
194
195 [Test]
196 public void TestDetachAttachmentToInventory()
197 {
198 TestHelpers.InMethod();
199// log4net.Config.XmlConfigurator.Configure();
200
201 AddPresence();
202
203 UUID attItemId = TestHelpers.ParseTail(0x2);
204 UUID attAssetId = TestHelpers.ParseTail(0x3);
205 string attName = "att";
206
207 UserInventoryHelpers.CreateInventoryItem(
208 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
209
210 m_attMod.RezSingleAttachmentFromInventory(
211 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
212 m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient);
213
214 // Check status on scene presence
215 Assert.That(m_presence.HasAttachments(), Is.False);
216 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
217 Assert.That(attachments.Count, Is.EqualTo(0));
218
219 // Check item status
220 Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
221 }
222
223 /// <summary>
224 /// Test that attachments don't hang about in the scene when the agent is closed
225 /// </summary>
226 [Test]
227 public void TestRemoveAttachmentsOnAvatarExit()
228 {
229 TestHelpers.InMethod();
230// log4net.Config.XmlConfigurator.Configure();
231
232 UUID userId = TestHelpers.ParseTail(0x1);
233 UUID attItemId = TestHelpers.ParseTail(0x2);
234 UUID attAssetId = TestHelpers.ParseTail(0x3);
235 string attName = "att";
236
237 UserAccountHelpers.CreateUserWithInventory(scene, userId);
238 InventoryItemBase attItem
239 = UserInventoryHelpers.CreateInventoryItem(
240 scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
241
242 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
243 acd.Appearance = new AvatarAppearance();
244 acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
245 ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
246
247 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
248
249 scene.IncomingCloseAgent(presence.UUID);
250
251 // Check that we can't retrieve this attachment from the scene.
252 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
253 }
254
255 [Test]
256 public void TestRezAttachmentsOnAvatarEntrance()
257 {
258 TestHelpers.InMethod();
259// log4net.Config.XmlConfigurator.Configure();
260
261 UUID userId = TestHelpers.ParseTail(0x1);
262 UUID attItemId = TestHelpers.ParseTail(0x2);
263 UUID attAssetId = TestHelpers.ParseTail(0x3);
264 string attName = "att";
265
266 UserAccountHelpers.CreateUserWithInventory(scene, userId);
267 InventoryItemBase attItem
268 = UserInventoryHelpers.CreateInventoryItem(
269 scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
270
271 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
272 acd.Appearance = new AvatarAppearance();
273 acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
274 ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
275
276 Assert.That(presence.HasAttachments(), Is.True);
277 List<SceneObjectGroup> attachments = presence.GetAttachments();
278
279 Assert.That(attachments.Count, Is.EqualTo(1));
280 SceneObjectGroup attSo = attachments[0];
281 Assert.That(attSo.Name, Is.EqualTo(attName));
282 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
283 Assert.That(attSo.IsAttachment);
284 Assert.That(attSo.UsesPhysics, Is.False);
285 Assert.That(attSo.IsTemporary, Is.False);
286
287 // Check appearance status
288 List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
289 Assert.That(retreivedAttachments.Count, Is.EqualTo(1));
290 Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
291 Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId));
292 Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId));
293 Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
294 }
295
296 // I'm commenting this test because scene setup NEEDS InventoryService to
297 // be non-null
298 //[Test]
299// public void T032_CrossAttachments()
300// {
301// TestHelpers.InMethod();
302//
303// ScenePresence presence = scene.GetScenePresence(agent1);
304// ScenePresence presence2 = scene2.GetScenePresence(agent1);
305// presence2.AddAttachment(sog1);
306// presence2.AddAttachment(sog2);
307//
308// ISharedRegionModule serialiser = new SerialiserModule();
309// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
310// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
311//
312// Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
313//
314// //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
315// Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
316// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
317// }
318 }
319} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index d02a305..b6a1564 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
104 public void NewClient(IClientAPI client) 104 public void NewClient(IClientAPI client)
105 { 105 {
106 client.OnRequestWearables += SendWearables; 106 client.OnRequestWearables += SendWearables;
107 client.OnSetAppearance += SetAppearance; 107 client.OnSetAppearance += SetAppearanceFromClient;
108 client.OnAvatarNowWearing += AvatarIsWearing; 108 client.OnAvatarNowWearing += AvatarIsWearing;
109 } 109 }
110 110
@@ -116,16 +116,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
116 #endregion 116 #endregion
117 117
118 /// <summary> 118 /// <summary>
119 /// Check for the existence of the baked texture assets. Request a rebake 119 /// Check for the existence of the baked texture assets.
120 /// unless checkonly is true.
121 /// </summary> 120 /// </summary>
122 /// <param name="client"></param> 121 /// <param name="client"></param>
123 /// <param name="checkonly"></param>
124 public bool ValidateBakedTextureCache(IClientAPI client) 122 public bool ValidateBakedTextureCache(IClientAPI client)
125 { 123 {
126 return ValidateBakedTextureCache(client, true); 124 return ValidateBakedTextureCache(client, true);
127 } 125 }
128 126
127 /// <summary>
128 /// Check for the existence of the baked texture assets. Request a rebake
129 /// unless checkonly is true.
130 /// </summary>
131 /// <param name="client"></param>
132 /// <param name="checkonly"></param>
129 private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly) 133 private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
130 { 134 {
131 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 135 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
@@ -147,6 +151,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
147 if (face == null) 151 if (face == null)
148 continue; 152 continue;
149 153
154// m_log.DebugFormat(
155// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
156// face.TextureID, idx, client.Name, client.AgentId);
157
150 // if the texture is one of the "defaults" then skip it 158 // if the texture is one of the "defaults" then skip it
151 // this should probably be more intelligent (skirt texture doesnt matter 159 // this should probably be more intelligent (skirt texture doesnt matter
152 // if the avatar isnt wearing a skirt) but if any of the main baked 160 // if the avatar isnt wearing a skirt) but if any of the main baked
@@ -156,13 +164,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
156 164
157 defonly = false; // found a non-default texture reference 165 defonly = false; // found a non-default texture reference
158 166
159 if (! CheckBakedTextureAsset(client,face.TextureID,idx)) 167 if (!CheckBakedTextureAsset(client, face.TextureID, idx))
160 { 168 {
161 // the asset didn't exist if we are only checking, then we found a bad 169 // the asset didn't exist if we are only checking, then we found a bad
162 // one and we're done otherwise, ask for a rebake 170 // one and we're done otherwise, ask for a rebake
163 if (checkonly) return false; 171 if (checkonly)
172 return false;
164 173
165 m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID); 174 m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID);
175
166 client.SendRebakeAvatarTextures(face.TextureID); 176 client.SendRebakeAvatarTextures(face.TextureID);
167 } 177 }
168 } 178 }
@@ -174,16 +184,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
174 } 184 }
175 185
176 /// <summary> 186 /// <summary>
177 /// Set appearance data (textureentry and slider settings) received from the client 187 /// Set appearance data (texture asset IDs and slider settings) received from the client
178 /// </summary> 188 /// </summary>
189 /// <param name="client"></param>
179 /// <param name="texture"></param> 190 /// <param name="texture"></param>
180 /// <param name="visualParam"></param> 191 /// <param name="visualParam"></param>
181 public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) 192 public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
182 { 193 {
183 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 194 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
184 if (sp == null) 195 if (sp == null)
185 { 196 {
186 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId); 197 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
187 return; 198 return;
188 } 199 }
189 200
@@ -211,18 +222,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
211 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; 222 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
212 223
213 m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId); 224 m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId);
214 Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); }); 225 Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client, false); });
215 226
216 // This appears to be set only in the final stage of the appearance 227 // This appears to be set only in the final stage of the appearance
217 // update transaction. In theory, we should be able to do an immediate 228 // update transaction. In theory, we should be able to do an immediate
218 // appearance send and save here. 229 // appearance send and save here.
219 230
220 // save only if there were changes, send no matter what (doesn't hurt to send twice)
221 if (changed)
222 QueueAppearanceSave(client.AgentId);
223 QueueAppearanceSend(client.AgentId);
224 } 231 }
232 // save only if there were changes, send no matter what (doesn't hurt to send twice)
233 if (changed)
234 QueueAppearanceSave(client.AgentId);
225 235
236 QueueAppearanceSend(client.AgentId);
226 } 237 }
227 238
228 // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); 239 // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
@@ -246,6 +257,117 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
246 return true; 257 return true;
247 } 258 }
248 259
260 public Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId)
261 {
262 ScenePresence sp = m_scene.GetScenePresence(agentId);
263
264 if (sp == null)
265 return new Dictionary<BakeType, Primitive.TextureEntryFace>();
266
267 return GetBakedTextureFaces(sp);
268 }
269
270 private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
271 {
272 if (sp.IsChildAgent)
273 return new Dictionary<BakeType, Primitive.TextureEntryFace>();
274
275 Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures
276 = new Dictionary<BakeType, Primitive.TextureEntryFace>();
277
278 AvatarAppearance appearance = sp.Appearance;
279 Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures;
280
281 foreach (int i in Enum.GetValues(typeof(BakeType)))
282 {
283 BakeType bakeType = (BakeType)i;
284
285 if (bakeType == BakeType.Unknown)
286 continue;
287
288// m_log.DebugFormat(
289// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
290// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
291
292 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
293 bakedTextures[bakeType] = faceTextures[ftIndex];
294 }
295
296 return bakedTextures;
297 }
298
299 public bool SaveBakedTextures(UUID agentId)
300 {
301 ScenePresence sp = m_scene.GetScenePresence(agentId);
302
303 if (sp == null)
304 return false;
305
306 m_log.DebugFormat(
307 "[AV FACTORY]: Permanently saving baked textures for {0} in {1}",
308 sp.Name, m_scene.RegionInfo.RegionName);
309
310 Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
311
312 if (bakedTextures.Count == 0)
313 return false;
314
315 foreach (BakeType bakeType in bakedTextures.Keys)
316 {
317 Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType];
318
319 if (bakedTextureFace == null)
320 {
321 m_log.WarnFormat(
322 "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently",
323 bakeType, sp.Name, m_scene.RegionInfo.RegionName);
324
325 continue;
326 }
327
328 AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString());
329
330 if (asset != null)
331 {
332 asset.Temporary = false;
333 asset.Local = false;
334 m_scene.AssetService.Store(asset);
335 }
336 else
337 {
338 m_log.WarnFormat(
339 "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently",
340 bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName);
341 }
342 }
343
344// for (int i = 0; i < faceTextures.Length; i++)
345// {
346//// m_log.DebugFormat(
347//// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
348//// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
349//
350// if (faceTextures[i] == null)
351// continue;
352//
353// AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString());
354//
355// if (asset != null)
356// {
357// asset.Temporary = false;
358// m_scene.AssetService.Store(asset);
359// }
360// else
361// {
362// m_log.WarnFormat(
363// "[AV FACTORY]: Baked texture {0} for {1} in {2} not found when trying to save permanently",
364// faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName);
365// }
366// }
367
368 return true;
369 }
370
249 #region UpdateAppearanceTimer 371 #region UpdateAppearanceTimer
250 372
251 /// <summary> 373 /// <summary>
@@ -278,26 +400,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
278 } 400 }
279 } 401 }
280 402
281 private void HandleAppearanceSend(UUID agentid) 403 private void SaveAppearance(UUID agentid)
282 { 404 {
283 ScenePresence sp = m_scene.GetScenePresence(agentid); 405 // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
284 if (sp == null) 406 // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
285 { 407 // number seperators.
286 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); 408 Culture.SetCurrentCulture();
287 return;
288 }
289
290 // m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid);
291 409
292 // Send the appearance to everyone in the scene
293 sp.SendAppearanceToAllOtherAgents();
294
295 // Send animations back to the avatar as well
296 sp.Animator.SendAnimPack();
297 }
298
299 private void HandleAppearanceSave(UUID agentid)
300 {
301 ScenePresence sp = m_scene.GetScenePresence(agentid); 410 ScenePresence sp = m_scene.GetScenePresence(agentid);
302 if (sp == null) 411 if (sp == null)
303 { 412 {
@@ -321,7 +430,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
321 { 430 {
322 if (kvp.Value < now) 431 if (kvp.Value < now)
323 { 432 {
324 Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); }); 433 Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); });
325 m_sendqueue.Remove(kvp.Key); 434 m_sendqueue.Remove(kvp.Key);
326 } 435 }
327 } 436 }
@@ -334,7 +443,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
334 { 443 {
335 if (kvp.Value < now) 444 if (kvp.Value < now)
336 { 445 {
337 Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); }); 446 Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); });
338 m_savequeue.Remove(kvp.Key); 447 m_savequeue.Remove(kvp.Key);
339 } 448 }
340 } 449 }
@@ -380,11 +489,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
380 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); 489 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
381 490
382 // we need to clean out the existing textures 491 // we need to clean out the existing textures
383 sp.Appearance.ResetAppearance(); 492 sp.Appearance.ResetAppearance();
384 493
385 // operate on a copy of the appearance so we don't have to lock anything 494 // operate on a copy of the appearance so we don't have to lock anything yet
386 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); 495 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
387 496
388 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) 497 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
389 { 498 {
390 if (wear.Type < AvatarWearable.MAX_WEARABLES) 499 if (wear.Type < AvatarWearable.MAX_WEARABLES)
@@ -396,12 +505,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
396 // This could take awhile since it needs to pull inventory 505 // This could take awhile since it needs to pull inventory
397 SetAppearanceAssets(sp.UUID, ref avatAppearance); 506 SetAppearanceAssets(sp.UUID, ref avatAppearance);
398 507
399 // could get fancier with the locks here, but in the spirit of "last write wins" 508 lock (m_setAppearanceLock)
400 // this should work correctly, also, we don't need to send the appearance here 509 {
401 // since the "iswearing" will trigger a new set of visual param and baked texture changes 510 // Update only those fields that we have changed. This is important because the viewer
402 // when those complete, the new appearance will be sent 511 // often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing
403 sp.Appearance = avatAppearance; 512 // shouldn't overwrite the changes made in SetAppearance.
404 QueueAppearanceSave(client.AgentId); 513 sp.Appearance.Wearables = avatAppearance.Wearables;
514 sp.Appearance.Texture = avatAppearance.Texture;
515
516 // We don't need to send the appearance here since the "iswearing" will trigger a new set
517 // of visual param and baked texture changes. When those complete, the new appearance will be sent
518
519 QueueAppearanceSave(client.AgentId);
520 }
521 }
522
523 public bool SendAppearance(UUID agentId)
524 {
525 ScenePresence sp = m_scene.GetScenePresence(agentId);
526 if (sp == null)
527 {
528 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
529 return false;
530 }
531
532 // Send the appearance to everyone in the scene
533 sp.SendAppearanceToAllOtherAgents();
534
535 // Send animations back to the avatar as well
536 sp.Animator.SendAnimPack();
537
538 return true;
405 } 539 }
406 540
407 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 541 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
new file mode 100644
index 0000000..7b2f14e
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -0,0 +1,120 @@
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 Nini.Config;
31using NUnit.Framework;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Region.CoreModules.Asset;
35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38
39namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
40{
41 [TestFixture]
42 public class AvatarFactoryModuleTests
43 {
44 /// <summary>
45 /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service.
46 /// </summary>
47 [Test]
48 public void TestSetAppearance()
49 {
50 TestHelpers.InMethod();
51// log4net.Config.XmlConfigurator.Configure();
52
53 UUID userId = TestHelpers.ParseTail(0x1);
54
55 AvatarFactoryModule afm = new AvatarFactoryModule();
56 TestScene scene = SceneHelpers.SetupScene();
57 SceneHelpers.SetupSceneModules(scene, afm);
58 IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
59
60 byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
61 for (byte i = 0; i < visualParams.Length; i++)
62 visualParams[i] = i;
63
64 afm.SetAppearanceFromClient(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
65
66 ScenePresence sp = scene.GetScenePresence(userId);
67
68 // TODO: Check baked texture
69 Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
70 }
71
72 [Test]
73 public void TestSaveBakedTextures()
74 {
75 TestHelpers.InMethod();
76// log4net.Config.XmlConfigurator.Configure();
77
78 UUID userId = TestHelpers.ParseTail(0x1);
79 UUID eyesTextureId = TestHelpers.ParseTail(0x2);
80
81 // We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly
82 // to the AssetService, which will then store temporary and local assets permanently
83 CoreAssetCache assetCache = new CoreAssetCache();
84
85 AvatarFactoryModule afm = new AvatarFactoryModule();
86 TestScene scene = SceneHelpers.SetupScene(assetCache);
87 SceneHelpers.SetupSceneModules(scene, afm);
88 IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
89
90 // TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules
91 AssetBase uploadedAsset;
92 uploadedAsset = new AssetBase(eyesTextureId, "Baked Texture", (sbyte)AssetType.Texture, userId.ToString());
93 uploadedAsset.Data = new byte[] { 2 };
94 uploadedAsset.Temporary = true;
95 uploadedAsset.Local = true; // Local assets aren't persisted, non-local are
96 scene.AssetService.Store(uploadedAsset);
97
98 byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
99 for (byte i = 0; i < visualParams.Length; i++)
100 visualParams[i] = i;
101
102 Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10));
103 uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes);
104 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
105 eyesFace.TextureID = eyesTextureId;
106
107 afm.SetAppearanceFromClient(tc, bakedTextureEntry, visualParams);
108 afm.SaveBakedTextures(userId);
109// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
110
111 // We should also inpsect the asset data store layer directly, but this is difficult to get at right now.
112 assetCache.Clear();
113
114 AssetBase eyesBake = scene.AssetService.Get(eyesTextureId.ToString());
115 Assert.That(eyesBake, Is.Not.Null);
116 Assert.That(eyesBake.Temporary, Is.False);
117 Assert.That(eyesBake.Local, Is.False);
118 }
119 }
120} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 1a0b914..3373bd5 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -172,69 +172,62 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
172 private void RetrieveInstantMessages(IClientAPI client) 172 private void RetrieveInstantMessages(IClientAPI client)
173 { 173 {
174 if (m_RestURL == String.Empty) 174 if (m_RestURL == String.Empty)
175 {
175 return; 176 return;
177 }
178 else
179 {
180 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
176 181
177 m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId); 182 List<GridInstantMessage> msglist
178 183 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
179 List<GridInstantMessage> msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
180 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); 184 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
181 185
182 if (msglist != null) 186 if (msglist != null)
183 {
184 foreach (GridInstantMessage im in msglist)
185 { 187 {
186 // client.SendInstantMessage(im); 188 foreach (GridInstantMessage im in msglist)
187 189 {
188 // Send through scene event manager so all modules get a chance 190 // client.SendInstantMessage(im);
189 // to look at this message before it gets delivered. 191
190 // 192 // Send through scene event manager so all modules get a chance
191 // Needed for proper state management for stored group 193 // to look at this message before it gets delivered.
192 // invitations 194 //
193 // 195 // Needed for proper state management for stored group
194 196 // invitations
195 im.offline = 1; 197 //
196 198
197 Scene s = FindScene(client.AgentId); 199 im.offline = 1;
198 if (s != null) 200
199 s.EventManager.TriggerIncomingInstantMessage(im); 201 Scene s = FindScene(client.AgentId);
202 if (s != null)
203 s.EventManager.TriggerIncomingInstantMessage(im);
204 }
200 } 205 }
201 } 206 }
202 } 207 }
203 208
204 private void UndeliveredMessage(GridInstantMessage im) 209 private void UndeliveredMessage(GridInstantMessage im)
205 { 210 {
206 if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && 211 if ((im.offline != 0)
207 im.dialog != (byte)InstantMessageDialog.MessageFromAgent && 212 && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
208 im.dialog != (byte)InstantMessageDialog.GroupNotice &&
209 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
210 im.dialog != (byte)InstantMessageDialog.InventoryOffered)
211 { 213 {
212 return; 214 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
213 } 215 "POST", m_RestURL + "/SaveMessage/", im);
214
215 // It's not delivered. Make sure the scope id is saved
216 // We don't need the imSessionID here anymore, overwrite it
217 Scene scene = FindScene(new UUID(im.fromAgentID));
218 if (scene == null)
219 scene = m_SceneList[0];
220
221 bool success = SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
222 "POST", m_RestURL+"/SaveMessage/?scope=" +
223 scene.RegionInfo.ScopeID.ToString(), im);
224 216
225 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 217 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
226 { 218 {
227 IClientAPI client = FindClient(new UUID(im.fromAgentID)); 219 IClientAPI client = FindClient(new UUID(im.fromAgentID));
228 if (client == null) 220 if (client == null)
229 return; 221 return;
230 222
231 client.SendInstantMessage(new GridInstantMessage( 223 client.SendInstantMessage(new GridInstantMessage(
232 null, new UUID(im.toAgentID), 224 null, new UUID(im.toAgentID),
233 "System", new UUID(im.fromAgentID), 225 "System", new UUID(im.fromAgentID),
234 (byte)InstantMessageDialog.MessageFromAgent, 226 (byte)InstantMessageDialog.MessageFromAgent,
235 "User is not logged in. "+ 227 "User is not logged in. " +
236 (success ? "Message saved." : "Message not saved"), 228 (success ? "Message saved." : "Message not saved"),
237 false, new Vector3())); 229 false, new Vector3()));
230 }
238 } 231 }
239 } 232 }
240 } 233 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
index aadeedb..19ef571 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
@@ -100,8 +100,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
100// log4net.Config.XmlConfigurator.Configure(); 100// log4net.Config.XmlConfigurator.Configure();
101 101
102 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 102 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
103 Scene scene = SceneSetupHelpers.SetupScene(); 103 Scene scene = SceneHelpers.SetupScene();
104 SceneSetupHelpers.SetupSceneModules(scene, archiverModule); 104 SceneHelpers.SetupSceneModules(scene, archiverModule);
105 105
106 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); 106 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
107 107
@@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
109 109
110 // Create scene object asset 110 // Create scene object asset
111 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 111 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
112 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50); 112 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50);
113 113
114 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 114 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
115 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 115 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -127,10 +127,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
127 scene.AddInventoryItem(item1); 127 scene.AddInventoryItem(item1);
128 128
129 // Create coalesced objects asset 129 // Create coalesced objects asset
130 SceneObjectGroup cobj1 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120); 130 SceneObjectGroup cobj1 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120);
131 cobj1.AbsolutePosition = new Vector3(15, 30, 45); 131 cobj1.AbsolutePosition = new Vector3(15, 30, 45);
132 132
133 SceneObjectGroup cobj2 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140); 133 SceneObjectGroup cobj2 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140);
134 cobj2.AbsolutePosition = new Vector3(25, 50, 75); 134 cobj2.AbsolutePosition = new Vector3(25, 50, 75);
135 135
136 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2); 136 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index ae3ab21..e409c8e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -61,14 +61,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
61 SerialiserModule serialiserModule = new SerialiserModule(); 61 SerialiserModule serialiserModule = new SerialiserModule();
62 m_archiverModule = new InventoryArchiverModule(); 62 m_archiverModule = new InventoryArchiverModule();
63 63
64 m_scene = SceneSetupHelpers.SetupScene(); 64 m_scene = SceneHelpers.SetupScene();
65 SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); 65 SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
66 } 66 }
67 67
68 [Test] 68 [Test]
69 public void TestLoadCoalesecedItem() 69 public void TestLoadCoalesecedItem()
70 { 70 {
71 TestHelper.InMethod(); 71 TestHelpers.InMethod();
72// log4net.Config.XmlConfigurator.Configure(); 72// log4net.Config.XmlConfigurator.Configure();
73 73
74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); 74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
104 [Test] 104 [Test]
105 public void TestOrder() 105 public void TestOrder()
106 { 106 {
107 TestHelper.InMethod(); 107 TestHelpers.InMethod();
108// log4net.Config.XmlConfigurator.Configure(); 108// log4net.Config.XmlConfigurator.Configure();
109 109
110 MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes); 110 MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes);
@@ -129,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
129 [Test] 129 [Test]
130 public void TestSaveItemToIar() 130 public void TestSaveItemToIar()
131 { 131 {
132 TestHelper.InMethod(); 132 TestHelpers.InMethod();
133// log4net.Config.XmlConfigurator.Configure(); 133// log4net.Config.XmlConfigurator.Configure();
134 134
135 // Create user 135 // Create user
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
141 141
142 // Create asset 142 // Create asset
143 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 143 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
144 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); 144 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
145 145
146 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 146 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
147 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 147 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -224,7 +224,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
224 [Test] 224 [Test]
225 public void TestSaveItemToIarNoAssets() 225 public void TestSaveItemToIarNoAssets()
226 { 226 {
227 TestHelper.InMethod(); 227 TestHelpers.InMethod();
228// log4net.Config.XmlConfigurator.Configure(); 228// log4net.Config.XmlConfigurator.Configure();
229 229
230 // Create user 230 // Create user
@@ -236,7 +236,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
236 236
237 // Create asset 237 // Create asset
238 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 238 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
239 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); 239 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
240 240
241 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 241 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
242 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 242 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
325 [Test] 325 [Test]
326 public void TestLoadIarCreatorAccountPresent() 326 public void TestLoadIarCreatorAccountPresent()
327 { 327 {
328 TestHelper.InMethod(); 328 TestHelpers.InMethod();
329// log4net.Config.XmlConfigurator.Configure(); 329// log4net.Config.XmlConfigurator.Configure();
330 330
331 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); 331 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
@@ -357,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
357 [Test] 357 [Test]
358 public void TestLoadIarV0_1SameNameCreator() 358 public void TestLoadIarV0_1SameNameCreator()
359 { 359 {
360 TestHelper.InMethod(); 360 TestHelpers.InMethod();
361// log4net.Config.XmlConfigurator.Configure(); 361// log4net.Config.XmlConfigurator.Configure();
362 362
363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); 363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
@@ -390,7 +390,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
390 [Test] 390 [Test]
391 public void TestLoadIarV0_1AbsentCreator() 391 public void TestLoadIarV0_1AbsentCreator()
392 { 392 {
393 TestHelper.InMethod(); 393 TestHelpers.InMethod();
394// log4net.Config.XmlConfigurator.Configure(); 394// log4net.Config.XmlConfigurator.Configure();
395 395
396 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); 396 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
index 127d5f8..417c20c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
@@ -57,13 +57,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
57 [Test] 57 [Test]
58 public void TestSavePathToIarV0_1() 58 public void TestSavePathToIarV0_1()
59 { 59 {
60 TestHelper.InMethod(); 60 TestHelpers.InMethod();
61// log4net.Config.XmlConfigurator.Configure(); 61// log4net.Config.XmlConfigurator.Configure();
62 62
63 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 63 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
64 64
65 Scene scene = SceneSetupHelpers.SetupScene(); 65 Scene scene = SceneHelpers.SetupScene();
66 SceneSetupHelpers.SetupSceneModules(scene, archiverModule); 66 SceneHelpers.SetupSceneModules(scene, archiverModule);
67 67
68 // Create user 68 // Create user
69 string userFirstName = "Jock"; 69 string userFirstName = "Jock";
@@ -172,16 +172,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
172 [Test] 172 [Test]
173 public void TestLoadIarToInventoryPaths() 173 public void TestLoadIarToInventoryPaths()
174 { 174 {
175 TestHelper.InMethod(); 175 TestHelpers.InMethod();
176// log4net.Config.XmlConfigurator.Configure(); 176// log4net.Config.XmlConfigurator.Configure();
177 177
178 SerialiserModule serialiserModule = new SerialiserModule(); 178 SerialiserModule serialiserModule = new SerialiserModule();
179 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 179 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
180 180
181 // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene 181 // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
182 Scene scene = SceneSetupHelpers.SetupScene(); 182 Scene scene = SceneHelpers.SetupScene();
183 183
184 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 184 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
185 185
186 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood"); 186 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood");
187 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); 187 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
@@ -217,13 +217,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
217 [Test] 217 [Test]
218 public void TestLoadIarPathStartsWithSlash() 218 public void TestLoadIarPathStartsWithSlash()
219 { 219 {
220 TestHelper.InMethod(); 220 TestHelpers.InMethod();
221// log4net.Config.XmlConfigurator.Configure(); 221// log4net.Config.XmlConfigurator.Configure();
222 222
223 SerialiserModule serialiserModule = new SerialiserModule(); 223 SerialiserModule serialiserModule = new SerialiserModule();
224 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 224 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
225 Scene scene = SceneSetupHelpers.SetupScene(); 225 Scene scene = SceneHelpers.SetupScene();
226 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 226 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
227 227
228 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); 228 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
229 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); 229 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
@@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
238 [Test] 238 [Test]
239 public void TestLoadIarPathWithEscapedChars() 239 public void TestLoadIarPathWithEscapedChars()
240 { 240 {
241 TestHelper.InMethod(); 241 TestHelpers.InMethod();
242// log4net.Config.XmlConfigurator.Configure(); 242// log4net.Config.XmlConfigurator.Configure();
243 243
244 string itemName = "You & you are a mean/man/"; 244 string itemName = "You & you are a mean/man/";
@@ -247,8 +247,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
247 247
248 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 248 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
249 249
250 Scene scene = SceneSetupHelpers.SetupScene(); 250 Scene scene = SceneHelpers.SetupScene();
251 SceneSetupHelpers.SetupSceneModules(scene, archiverModule); 251 SceneHelpers.SetupSceneModules(scene, archiverModule);
252 252
253 // Create user 253 // Create user
254 string userFirstName = "Jock"; 254 string userFirstName = "Jock";
@@ -323,10 +323,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
323 [Test] 323 [Test]
324 public void TestNewIarPath() 324 public void TestNewIarPath()
325 { 325 {
326 TestHelper.InMethod(); 326 TestHelpers.InMethod();
327// log4net.Config.XmlConfigurator.Configure(); 327// log4net.Config.XmlConfigurator.Configure();
328 328
329 Scene scene = SceneSetupHelpers.SetupScene(); 329 Scene scene = SceneHelpers.SetupScene();
330 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 330 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
331 331
332 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); 332 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
@@ -390,10 +390,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
390 [Test] 390 [Test]
391 public void TestPartExistingIarPath() 391 public void TestPartExistingIarPath()
392 { 392 {
393 TestHelper.InMethod(); 393 TestHelpers.InMethod();
394 //log4net.Config.XmlConfigurator.Configure(); 394 //log4net.Config.XmlConfigurator.Configure();
395 395
396 Scene scene = SceneSetupHelpers.SetupScene(); 396 Scene scene = SceneHelpers.SetupScene();
397 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 397 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
398 398
399 string folder1ExistingName = "a"; 399 string folder1ExistingName = "a";
@@ -441,10 +441,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
441 [Test] 441 [Test]
442 public void TestMergeIarPath() 442 public void TestMergeIarPath()
443 { 443 {
444 TestHelper.InMethod(); 444 TestHelpers.InMethod();
445// log4net.Config.XmlConfigurator.Configure(); 445// log4net.Config.XmlConfigurator.Configure();
446 446
447 Scene scene = SceneSetupHelpers.SetupScene(); 447 Scene scene = SceneHelpers.SetupScene();
448 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 448 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
449 449
450 string folder1ExistingName = "a"; 450 string folder1ExistingName = "a";
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 528bc8d..120fd43 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -208,9 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
208 Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); 208 Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length);
209 209
210 if (user != null) 210 if (user != null)
211 {
212 user.ControllingClient.SendBulkUpdateInventory(folderCopy); 211 user.ControllingClient.SendBulkUpdateInventory(folderCopy);
213 }
214 212
215 // HACK!! 213 // HACK!!
216 im.imSessionID = folderID.Guid; 214 im.imSessionID = folderID.Guid;
@@ -240,9 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
240 Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); 238 Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16);
241 239
242 if (user != null) 240 if (user != null)
243 {
244 user.ControllingClient.SendBulkUpdateInventory(itemCopy); 241 user.ControllingClient.SendBulkUpdateInventory(itemCopy);
245 }
246 242
247 // HACK!! 243 // HACK!!
248 im.imSessionID = itemID.Guid; 244 im.imSessionID = itemID.Guid;
@@ -280,7 +276,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
280 else 276 else
281 { 277 {
282 if (m_TransferModule != null) 278 if (m_TransferModule != null)
283 m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); 279 m_TransferModule.SendInstantMessage(im, delegate(bool success) {
280 // Send BulkUpdateInventory
281 IInventoryService invService = scene.InventoryService;
282 UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
283
284 InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
285 folder = invService.GetFolder(folder);
286
287 ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
288
289 // If the user has left the scene by the time the message comes back then we can't send
290 // them the update.
291 if (fromUser != null)
292 fromUser.ControllingClient.SendBulkUpdateInventory(folder);
293 });
284 } 294 }
285 } 295 }
286 else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) 296 else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index c82cfd2..d687e6a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -196,7 +196,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
196 if (!(client.Scene is Scene)) 196 if (!(client.Scene is Scene))
197 return; 197 return;
198 198
199 Scene scene = (Scene)(client.Scene); 199// Scene scene = (Scene)(client.Scene);
200 200
201 GridInstantMessage im = null; 201 GridInstantMessage im = null;
202 if (m_PendingLures.TryGetValue(lureID, out im)) 202 if (m_PendingLures.TryGetValue(lureID, out im))
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
index 079e1b6..dee0ad4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
@@ -134,7 +134,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
134 if (!(s is Scene)) 134 if (!(s is Scene))
135 return; 135 return;
136 136
137 Scene scene = (Scene)s; 137// Scene scene = (Scene)s;
138 138
139 string profileUrl = String.Empty; 139 string profileUrl = String.Empty;
140 string aboutText = String.Empty; 140 string aboutText = String.Empty;
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 90f0ca2..25d5e0e 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -59,7 +59,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
59 get { return m_MaxTransferDistance; } 59 get { return m_MaxTransferDistance; }
60 set { m_MaxTransferDistance = value; } 60 set { m_MaxTransferDistance = value; }
61 } 61 }
62
63 62
64 protected bool m_Enabled = false; 63 protected bool m_Enabled = false;
65 protected Scene m_aScene; 64 protected Scene m_aScene;
@@ -68,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
68 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = 67 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
69 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); 68 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
70 69
71
72 #region ISharedRegionModule 70 #region ISharedRegionModule
73 71
74 public Type ReplaceableInterface 72 public Type ReplaceableInterface
@@ -209,8 +207,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
209 sp.TeleportFlags = (TeleportFlags)teleportFlags; 207 sp.TeleportFlags = (TeleportFlags)teleportFlags;
210 sp.Teleport(position); 208 sp.Teleport(position);
211 209
212 foreach (SceneObjectGroup grp in sp.Attachments) 210 foreach (SceneObjectGroup grp in sp.GetAttachments())
213 sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); 211 {
212 if (grp.IsDeleted)
213 sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
214 }
214 } 215 }
215 else // Another region possibly in another simulator 216 else // Another region possibly in another simulator
216 { 217 {
@@ -328,10 +329,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
328 sp.StandUp(); 329 sp.StandUp();
329 330
330 if (!sp.ValidateAttachments()) 331 if (!sp.ValidateAttachments())
331 { 332 m_log.DebugFormat(
332 sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); 333 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
333 return; 334 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
334 } 335
336// if (!sp.ValidateAttachments())
337// {
338// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
339// return;
340// }
335 341
336 string reason; 342 string reason;
337 string version; 343 string version;
@@ -494,7 +500,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
494 // Now let's make it officially a child agent 500 // Now let's make it officially a child agent
495 sp.MakeChildAgent(); 501 sp.MakeChildAgent();
496 502
497 sp.Scene.CleanDroppedAttachments(); 503// sp.Scene.CleanDroppedAttachments();
498 504
499 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 505 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
500 506
@@ -560,11 +566,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
560 566
561 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) 567 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
562 { 568 {
563 foreach (SceneObjectGroup sop in sp.Attachments) 569 sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true);
564 {
565 sop.Scene.DeleteSceneObject(sop, true);
566 }
567 sp.Attachments.Clear();
568 } 570 }
569 571
570 protected void KillEntity(Scene scene, uint localID) 572 protected void KillEntity(Scene scene, uint localID)
@@ -959,7 +961,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
959 /// This Closes child agents on neighbouring regions 961 /// This Closes child agents on neighbouring regions
960 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 962 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
961 /// </summary> 963 /// </summary>
962 protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) 964 protected ScenePresence CrossAgentToNewRegionAsync(
965 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
966 bool isFlying, string version)
963 { 967 {
964 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 968 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
965 969
@@ -967,8 +971,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
967 971
968 Scene m_scene = agent.Scene; 972 Scene m_scene = agent.Scene;
969 973
970 if (neighbourRegion != null && agent.ValidateAttachments()) 974 if (neighbourRegion != null)
971 { 975 {
976 if (!agent.ValidateAttachments())
977 m_log.DebugFormat(
978 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
979 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
980
972 pos = pos + (agent.Velocity); 981 pos = pos + (agent.Velocity);
973 982
974 SetInTransit(agent.UUID); 983 SetInTransit(agent.UUID);
@@ -1088,10 +1097,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1088 #endregion 1097 #endregion
1089 1098
1090 #region Enable Child Agent 1099 #region Enable Child Agent
1100
1091 /// <summary> 1101 /// <summary>
1092 /// This informs a single neighbouring region about agent "avatar". 1102 /// This informs a single neighbouring region about agent "avatar".
1093 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1103 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1094 /// </summary> 1104 /// </summary>
1105 /// <param name="sp"></param>
1106 /// <param name="region"></param>
1095 public void EnableChildAgent(ScenePresence sp, GridRegion region) 1107 public void EnableChildAgent(ScenePresence sp, GridRegion region)
1096 { 1108 {
1097 m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName); 1109 m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName);
@@ -1153,6 +1165,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1153 /// This informs all neighbouring regions about agent "avatar". 1165 /// This informs all neighbouring regions about agent "avatar".
1154 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1166 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1155 /// </summary> 1167 /// </summary>
1168 /// <param name="sp"></param>
1156 public void EnableChildAgents(ScenePresence sp) 1169 public void EnableChildAgents(ScenePresence sp)
1157 { 1170 {
1158 List<GridRegion> neighbours = new List<GridRegion>(); 1171 List<GridRegion> neighbours = new List<GridRegion>();
@@ -1340,7 +1353,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1340 Utils.LongToUInts(reg.RegionHandle, out x, out y); 1353 Utils.LongToUInts(reg.RegionHandle, out x, out y);
1341 x = x / Constants.RegionSize; 1354 x = x / Constants.RegionSize;
1342 y = y / Constants.RegionSize; 1355 y = y / Constants.RegionSize;
1343 m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")"); 1356 m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint + ")");
1344 1357
1345 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); 1358 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath);
1346 1359
@@ -1786,34 +1799,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1786 1799
1787 protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent) 1800 protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent)
1788 { 1801 {
1789 List<SceneObjectGroup> m_attachments = sp.Attachments; 1802 List<SceneObjectGroup> m_attachments = sp.GetAttachments();
1790 lock (m_attachments) 1803
1804 // Validate
1805// foreach (SceneObjectGroup gobj in m_attachments)
1806// {
1807// if (gobj == null || gobj.IsDeleted)
1808// return false;
1809// }
1810
1811 foreach (SceneObjectGroup gobj in m_attachments)
1791 { 1812 {
1792 // Validate 1813 // If the prim group is null then something must have happened to it!
1793 foreach (SceneObjectGroup gobj in m_attachments) 1814 if (gobj != null && !gobj.IsDeleted)
1794 { 1815 {
1795 if (gobj == null || gobj.IsDeleted) 1816 // Set the parent localID to 0 so it transfers over properly.
1796 return false; 1817 gobj.RootPart.SetParentLocalId(0);
1818 gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
1819 gobj.IsAttachment = false;
1820 //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
1821 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
1822 CrossPrimGroupIntoNewRegion(destination, gobj, silent);
1797 } 1823 }
1824 }
1798 1825
1799 foreach (SceneObjectGroup gobj in m_attachments) 1826 sp.ClearAttachments();
1800 {
1801 // If the prim group is null then something must have happened to it!
1802 if (gobj != null && gobj.RootPart != null)
1803 {
1804 // Set the parent localID to 0 so it transfers over properly.
1805 gobj.RootPart.SetParentLocalId(0);
1806 gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
1807 gobj.RootPart.IsAttachment = false;
1808 //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
1809 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
1810 CrossPrimGroupIntoNewRegion(destination, gobj, silent);
1811 }
1812 }
1813 m_attachments.Clear();
1814 1827
1815 return true; 1828 return true;
1816 }
1817 } 1829 }
1818 1830
1819 #endregion 1831 #endregion
@@ -1862,7 +1874,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1862 int i = 0; 1874 int i = 0;
1863 if (sp.InTransitScriptStates.Count > 0) 1875 if (sp.InTransitScriptStates.Count > 0)
1864 { 1876 {
1865 sp.Attachments.ForEach(delegate(SceneObjectGroup sog) 1877 List<SceneObjectGroup> attachments = sp.GetAttachments();
1878
1879 foreach (SceneObjectGroup sog in attachments)
1866 { 1880 {
1867 if (i < sp.InTransitScriptStates.Count) 1881 if (i < sp.InTransitScriptStates.Count)
1868 { 1882 {
@@ -1871,8 +1885,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1871 sog.ResumeScripts(); 1885 sog.ResumeScripts();
1872 } 1886 }
1873 else 1887 else
1874 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}", sp.InTransitScriptStates.Count, sp.Attachments.Count); 1888 m_log.ErrorFormat(
1875 }); 1889 "[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}",
1890 sp.InTransitScriptStates.Count, attachments.Count);
1891 }
1876 1892
1877 sp.InTransitScriptStates.Clear(); 1893 sp.InTransitScriptStates.Clear();
1878 } 1894 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index a98ce85..f05b090 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
325 } 325 }
326 } 326 }
327 327
328 // This is pethod scoped and will be returned. It will be the 328 // This is method scoped and will be returned. It will be the
329 // last created asset id 329 // last created asset id
330 UUID assetID = UUID.Zero; 330 UUID assetID = UUID.Zero;
331 331
@@ -354,9 +354,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
354 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); 354 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
355 Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); 355 Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();
356 356
357 Dictionary<UUID, string> xmlStrings =
358 new Dictionary<UUID, string>();
359
360 foreach (SceneObjectGroup objectGroup in objlist) 357 foreach (SceneObjectGroup objectGroup in objlist)
361 { 358 {
362 Vector3 inventoryStoredPosition = new Vector3 359 Vector3 inventoryStoredPosition = new Vector3
@@ -369,12 +366,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
369 : objectGroup.AbsolutePosition.Y, 366 : objectGroup.AbsolutePosition.Y,
370 objectGroup.AbsolutePosition.Z); 367 objectGroup.AbsolutePosition.Z);
371 368
372 Vector3 originalPosition = objectGroup.AbsolutePosition; 369 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
373
374 // Restore attachment data after trip through the sim
375 if (objectGroup.RootPart.AttachPoint > 0)
376 inventoryStoredPosition = objectGroup.RootPart.AttachOffset;
377 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
378 370
379 objectGroup.AbsolutePosition = inventoryStoredPosition; 371 objectGroup.AbsolutePosition = inventoryStoredPosition;
380 372
@@ -388,60 +380,159 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
388 (uint)PermissionMask.Modify); 380 (uint)PermissionMask.Modify);
389 objectGroup.RootPart.NextOwnerMask |= 381 objectGroup.RootPart.NextOwnerMask |=
390 (uint)PermissionMask.Move; 382 (uint)PermissionMask.Move;
383
384 coa.Add(objectGroup);
385 }
391 386
392 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); 387 string itemXml;
393 388
394 objectGroup.AbsolutePosition = originalPosition; 389 if (objlist.Count > 1)
390 itemXml = CoalescedSceneObjectsSerializer.ToXml(coa);
391 else
392 itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]);
393
394 // Restore the position of each group now that it has been stored to inventory.
395 foreach (SceneObjectGroup objectGroup in objlist)
396 objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
395 397
396 xmlStrings[objectGroup.UUID] = sceneObjectXml; 398 InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
399 if (item == null)
400 return UUID.Zero;
401
402 // Can't know creator is the same, so null it in inventory
403 if (objlist.Count > 1)
404 {
405 item.CreatorId = UUID.Zero.ToString();
406 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
397 } 407 }
408 else
409 {
410 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
411 item.SaleType = objlist[0].RootPart.ObjectSaleType;
412 item.SalePrice = objlist[0].RootPart.SalePrice;
413 }
398 414
399 string itemXml; 415 AssetBase asset = CreateAsset(
416 objlist[0].GetPartName(objlist[0].RootPart.LocalId),
417 objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
418 (sbyte)AssetType.Object,
419 Utils.StringToBytes(itemXml),
420 objlist[0].OwnerID.ToString());
421 m_Scene.AssetService.Store(asset);
422
423 item.AssetID = asset.FullID;
424 assetID = asset.FullID;
400 425
401 if (objlist.Count > 1) 426 if (DeRezAction.SaveToExistingUserInventoryItem == action)
427 {
428 m_Scene.InventoryService.UpdateItem(item);
429 }
430 else
402 { 431 {
403 float minX, minY, minZ; 432 AddPermissions(item, objlist[0], objlist, remoteClient);
404 float maxX, maxY, maxZ;
405 433
406 Vector3[] offsets = Scene.GetCombinedBoundingBox(objlist, 434 item.CreationDate = Util.UnixTimeSinceEpoch();
407 out minX, out maxX, out minY, out maxY, 435 item.Description = asset.Description;
408 out minZ, out maxZ); 436 item.Name = asset.Name;
437 item.AssetType = asset.Type;
409 438
410 // CreateWrapper 439 m_Scene.AddInventoryItem(item);
411 XmlDocument itemDoc = new XmlDocument();
412 XmlElement root = itemDoc.CreateElement("", "CoalescedObject", "");
413 itemDoc.AppendChild(root);
414 440
415 // Embed the offsets into the group XML 441 if (remoteClient != null && item.Owner == remoteClient.AgentId)
416 for ( int i = 0 ; i < objlist.Count ; i++ ) 442 {
443 remoteClient.SendInventoryItemCreateUpdate(item, 0);
444 }
445 else
417 { 446 {
418 XmlDocument doc = new XmlDocument(); 447 ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
419 SceneObjectGroup g = objlist[i]; 448 if (notifyUser != null)
420 doc.LoadXml(xmlStrings[g.UUID]); 449 {
421 XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup"); 450 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
422 e.SetAttribute("offsetx", offsets[i].X.ToString()); 451 }
423 e.SetAttribute("offsety", offsets[i].Y.ToString());
424 e.SetAttribute("offsetz", offsets[i].Z.ToString());
425
426 XmlNode objectNode = itemDoc.ImportNode(e, true);
427 root.AppendChild(objectNode);
428 } 452 }
453 }
429 454
430 float sizeX = maxX - minX; 455 // This is a hook to do some per-asset post-processing for subclasses that need that
431 float sizeY = maxY - minY; 456 if (remoteClient != null)
432 float sizeZ = maxZ - minZ; 457 ExportAsset(remoteClient.AgentId, assetID);
458
459 return assetID;
460 }
433 461
434 root.SetAttribute("x", sizeX.ToString()); 462 protected virtual void ExportAsset(UUID agentID, UUID assetID)
435 root.SetAttribute("y", sizeY.ToString()); 463 {
436 root.SetAttribute("z", sizeZ.ToString()); 464 // nothing to do here
465 }
466
467 /// <summary>
468 /// Add relevant permissions for an object to the item.
469 /// </summary>
470 /// <param name="item"></param>
471 /// <param name="so"></param>
472 /// <param name="objsForEffectivePermissions"></param>
473 /// <param name="remoteClient"></param>
474 /// <returns></returns>
475 protected InventoryItemBase AddPermissions(
476 InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions,
477 IClientAPI remoteClient)
478 {
479 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7;
480 foreach (SceneObjectGroup grp in objsForEffectivePermissions)
481 effectivePerms &= grp.GetEffectivePermissions();
482 effectivePerms |= (uint)PermissionMask.Move;
437 483
438 itemXml = itemDoc.InnerXml; 484 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
485 {
486 uint perms = effectivePerms;
487 uint nextPerms = (perms & 7) << 13;
488 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
489 perms &= ~(uint)PermissionMask.Copy;
490 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
491 perms &= ~(uint)PermissionMask.Transfer;
492 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
493 perms &= ~(uint)PermissionMask.Modify;
494
495 item.BasePermissions = perms & so.RootPart.NextOwnerMask;
496 item.CurrentPermissions = item.BasePermissions;
497 item.NextPermissions = perms & so.RootPart.NextOwnerMask;
498 item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask;
499 item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask;
500
501 // Magic number badness. Maybe this deserves an enum.
502 // bit 4 (16) is the "Slam" bit, it means treat as passed
503 // and apply next owner perms on rez
504 item.CurrentPermissions |= 16; // Slam!
439 } 505 }
440 else 506 else
441 { 507 {
442 itemXml = xmlStrings[objlist[0].UUID]; 508 item.BasePermissions = effectivePerms;
443 } 509 item.CurrentPermissions = effectivePerms;
510 item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms;
511 item.EveryOnePermissions = so.RootPart.EveryoneMask & effectivePerms;
512 item.GroupPermissions = so.RootPart.GroupMask & effectivePerms;
444 513
514 item.CurrentPermissions &=
515 ((uint)PermissionMask.Copy |
516 (uint)PermissionMask.Transfer |
517 (uint)PermissionMask.Modify |
518 (uint)PermissionMask.Move |
519 7); // Preserve folded permissions
520 }
521
522 return item;
523 }
524
525 /// <summary>
526 /// Create an item using details for the given scene object.
527 /// </summary>
528 /// <param name="action"></param>
529 /// <param name="remoteClient"></param>
530 /// <param name="so"></param>
531 /// <param name="folderID"></param>
532 /// <returns></returns>
533 protected InventoryItemBase CreateItemForObject(
534 DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID)
535 {
445 // Get the user info of the item destination 536 // Get the user info of the item destination
446 // 537 //
447 UUID userID = UUID.Zero; 538 UUID userID = UUID.Zero;
@@ -453,7 +544,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
453 // Saving changes requires a local user 544 // Saving changes requires a local user
454 // 545 //
455 if (remoteClient == null) 546 if (remoteClient == null)
456 return UUID.Zero; 547 return null;
457 548
458 userID = remoteClient.AgentId; 549 userID = remoteClient.AgentId;
459 } 550 }
@@ -461,13 +552,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
461 { 552 {
462 // All returns / deletes go to the object owner 553 // All returns / deletes go to the object owner
463 // 554 //
464 555 userID = so.RootPart.OwnerID;
465 userID = objlist[0].RootPart.OwnerID;
466 } 556 }
467 557
468 if (userID == UUID.Zero) // Can't proceed 558 if (userID == UUID.Zero) // Can't proceed
469 { 559 {
470 return UUID.Zero; 560 return null;
471 } 561 }
472 562
473 // If we're returning someone's item, it goes back to the 563 // If we're returning someone's item, it goes back to the
@@ -475,13 +565,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
475 // Delete is treated like return in this case 565 // Delete is treated like return in this case
476 // Deleting your own items makes them go to trash 566 // Deleting your own items makes them go to trash
477 // 567 //
478 568
479 InventoryFolderBase folder = null; 569 InventoryFolderBase folder = null;
480 InventoryItemBase item = null; 570 InventoryItemBase item = null;
481 571
482 if (DeRezAction.SaveToExistingUserInventoryItem == action) 572 if (DeRezAction.SaveToExistingUserInventoryItem == action)
483 { 573 {
484 item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID); 574 item = new InventoryItemBase(so.RootPart.FromUserInventoryItemID, userID);
485 item = m_Scene.InventoryService.GetItem(item); 575 item = m_Scene.InventoryService.GetItem(item);
486 576
487 //item = userInfo.RootFolder.FindItem( 577 //item = userInfo.RootFolder.FindItem(
@@ -491,8 +581,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
491 { 581 {
492 m_log.DebugFormat( 582 m_log.DebugFormat(
493 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", 583 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
494 objlist[0].Name, objlist[0].UUID); 584 so.Name, so.UUID);
495 return UUID.Zero; 585
586 return null;
496 } 587 }
497 } 588 }
498 else 589 else
@@ -504,19 +595,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
504 // Deleting someone else's item 595 // Deleting someone else's item
505 // 596 //
506 if (remoteClient == null || 597 if (remoteClient == null ||
507 objlist[0].OwnerID != remoteClient.AgentId) 598 so.OwnerID != remoteClient.AgentId)
508 { 599 {
509
510 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 600 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
511 } 601 }
512 else 602 else
513 { 603 {
514 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); 604 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
515 } 605 }
516 } 606 }
517 else if (action == DeRezAction.Return) 607 else if (action == DeRezAction.Return)
518 { 608 {
519
520 // Dump to lost + found unconditionally 609 // Dump to lost + found unconditionally
521 // 610 //
522 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 611 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
@@ -532,8 +621,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
532 } 621 }
533 else 622 else
534 { 623 {
535 if (remoteClient == null || 624 if (remoteClient == null || so.OwnerID != remoteClient.AgentId)
536 objlist[0].OwnerID != remoteClient.AgentId)
537 { 625 {
538 // Taking copy of another person's item. Take to 626 // Taking copy of another person's item. Take to
539 // Objects folder. 627 // Objects folder.
@@ -554,9 +642,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
554 // 642 //
555 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) 643 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
556 { 644 {
557 if (objlist[0].RootPart.FromFolderID != UUID.Zero && objlist[0].OwnerID == remoteClient.AgentId) 645 if (so.RootPart.FromFolderID != UUID.Zero)
558 { 646 {
559 InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID); 647 InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
560 folder = m_Scene.InventoryService.GetFolder(f); 648 folder = m_Scene.InventoryService.GetFolder(f);
561 } 649 }
562 } 650 }
@@ -567,406 +655,229 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
567 655
568 if (folder == null) // Nowhere to put it 656 if (folder == null) // Nowhere to put it
569 { 657 {
570 return UUID.Zero; 658 return null;
571 } 659 }
572 } 660 }
573 661
574 item = new InventoryItemBase(); 662 item = new InventoryItemBase();
575 // Can't know creator is the same, so null it in inventory
576 if (objlist.Count > 1)
577 {
578 item.CreatorId = UUID.Zero.ToString();
579 item.CreatorData = String.Empty;
580 }
581 else
582 {
583 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
584 item.CreatorData = objlist[0].RootPart.CreatorData;
585 }
586 item.ID = UUID.Random(); 663 item.ID = UUID.Random();
587 item.InvType = (int)InventoryType.Object; 664 item.InvType = (int)InventoryType.Object;
588 item.Folder = folder.ID; 665 item.Folder = folder.ID;
589 item.Owner = userID; 666 item.Owner = userID;
590 if (objlist.Count > 1) 667 }
591 { 668
592 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; 669 return item;
593 } 670 }
594 else
595 {
596 item.SaleType = objlist[0].RootPart.ObjectSaleType;
597 item.SalePrice = objlist[0].RootPart.SalePrice;
598 }
599 }
600 671
601 AssetBase asset = CreateAsset( 672 public virtual SceneObjectGroup RezObject(
602 objlist[0].GetPartName(objlist[0].RootPart.LocalId), 673 IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
603 objlist[0].GetPartDescription(objlist[0].RootPart.LocalId), 674 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
604 (sbyte)AssetType.Object, 675 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
605 Utils.StringToBytes(itemXml), 676 {
606 objlist[0].OwnerID.ToString()); 677// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
607 m_Scene.AssetService.Store(asset); 678 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
608 assetID = asset.FullID; 679 item = m_Scene.InventoryService.GetItem(item);
609 680
610 if (DeRezAction.SaveToExistingUserInventoryItem == action) 681 if (item == null)
611 { 682 {
612 item.AssetID = asset.FullID; 683
613 m_Scene.InventoryService.UpdateItem(item); 684 return null;
614 } 685 }
615 else
616 {
617 item.AssetID = asset.FullID;
618 686
619 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7;
620 foreach (SceneObjectGroup grp in objlist)
621 effectivePerms &= grp.GetEffectivePermissions();
622 effectivePerms |= (uint)PermissionMask.Move;
623 687
624 if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
625 {
626 uint perms = effectivePerms;
627 uint nextPerms = (perms & 7) << 13;
628 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
629 perms &= ~(uint)PermissionMask.Copy;
630 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
631 perms &= ~(uint)PermissionMask.Transfer;
632 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
633 perms &= ~(uint)PermissionMask.Modify;
634
635 item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask;
636 item.CurrentPermissions = item.BasePermissions;
637 item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask;
638 item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask;
639 item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask;
640
641 item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
642 }
643 else
644 {
645 item.BasePermissions = effectivePerms;
646 item.CurrentPermissions = effectivePerms;
647 item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms;
648 item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms;
649 item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms;
650
651 item.CurrentPermissions &=
652 ((uint)PermissionMask.Copy |
653 (uint)PermissionMask.Transfer |
654 (uint)PermissionMask.Modify |
655 (uint)PermissionMask.Move |
656 7); // Preserve folded permissions
657 }
658 688
659 item.CreationDate = Util.UnixTimeSinceEpoch();
660 item.Description = asset.Description;
661 item.Name = asset.Name;
662 item.AssetType = asset.Type;
663 689
664 m_Scene.AddInventoryItem(item);
665 690
666 if (remoteClient != null && item.Owner == remoteClient.AgentId) 691
692
693 item.Owner = remoteClient.AgentId;
694
695 return RezObject(
696 remoteClient, item, item.AssetID,
697 RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
698 RezSelected, RemoveItem, fromTaskID, attachment);
699 }
700
701 public virtual SceneObjectGroup RezObject(
702 IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart,
703 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
704 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
705 {
706 AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());
707
708 if (rezAsset == null)
709 {
710 if (item != null)
667 { 711 {
668 remoteClient.SendInventoryItemCreateUpdate(item, 0); 712 m_log.WarnFormat(
713 "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()",
714 assetID, item.Name, item.ID, remoteClient.Name);
669 } 715 }
670 else 716 else
671 { 717 {
672 ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); 718 m_log.WarnFormat(
673 if (notifyUser != null) 719 "[InventoryAccessModule]: Could not find asset {0} for {1} in RezObject()",
674 { 720 assetID, remoteClient.Name);
675 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
676 }
677 } 721 }
678 }
679 722
680 // This is a hook to do some per-asset post-processing for subclasses that need that 723 return null;
681 if (remoteClient != null) 724 }
682 ExportAsset(remoteClient.AgentId, assetID);
683
684 return assetID;
685 }
686 725
687 protected virtual void ExportAsset(UUID agentID, UUID assetID) 726 SceneObjectGroup group = null;
688 {
689 // nothing to do here
690 }
691 727
692 /// <summary> 728 string xmlData = Utils.BytesToString(rezAsset.Data);
693 /// Rez an object into the scene from the user's inventory 729 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>();
694 /// </summary> 730 List<Vector3> veclist = new List<Vector3>();
695 /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing 731 byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
696 /// things to the scene. The caller should be doing that, I think. 732 Vector3 pos;
697 /// <param name="remoteClient"></param>
698 /// <param name="itemID"></param>
699 /// <param name="RayEnd"></param>
700 /// <param name="RayStart"></param>
701 /// <param name="RayTargetID"></param>
702 /// <param name="BypassRayCast"></param>
703 /// <param name="RayEndIsIntersection"></param>
704 /// <param name="RezSelected"></param>
705 /// <param name="RemoveItem"></param>
706 /// <param name="fromTaskID"></param>
707 /// <param name="attachment"></param>
708 /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
709 public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
710 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
711 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
712 {
713 // Work out position details
714 byte bRayEndIsIntersection = (byte)0;
715 733
716 if (RayEndIsIntersection) 734 XmlDocument doc = new XmlDocument();
735 doc.LoadXml(xmlData);
736 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
737 if (e == null || attachment) // Single
717 { 738 {
718 bRayEndIsIntersection = (byte)1; 739 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
740
741 objlist.Add(g);
742 veclist.Add(new Vector3(0, 0, 0));
743
744 float offsetHeight = 0;
745 pos = m_Scene.GetNewRezLocation(
746 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
747 BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false);
748 pos.Z += offsetHeight;
719 } 749 }
720 else 750 else
721 { 751 {
722 bRayEndIsIntersection = (byte)0; 752 XmlElement coll = (XmlElement)e;
723 } 753 float bx = Convert.ToSingle(coll.GetAttribute("x"));
724 754 float by = Convert.ToSingle(coll.GetAttribute("y"));
725 Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); 755 float bz = Convert.ToSingle(coll.GetAttribute("z"));
756 Vector3 bbox = new Vector3(bx, by, bz);
726 757
758 pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
759 RayTargetID, Quaternion.Identity,
760 BypassRayCast, bRayEndIsIntersection, true,
761 bbox, false);
727 762
728 Vector3 pos = m_Scene.GetNewRezLocation( 763 pos -= bbox / 2;
729 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
730 BypassRayCast, bRayEndIsIntersection, true, scale, false);
731 764
732 // Rez object 765 XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
733 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 766 foreach (XmlNode n in groups)
734 item = m_Scene.InventoryService.GetItem(item);
735
736 if (item != null)
737 {
738 if (item.ID == UUID.Zero)
739 { 767 {
740 m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 1"); 768 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
769
770 objlist.Add(g);
771 XmlElement el = (XmlElement)n;
772
773 string rawX = el.GetAttribute("offsetx");
774 string rawY = el.GetAttribute("offsety");
775 string rawZ = el.GetAttribute("offsetz");
776//
777// m_log.DebugFormat(
778// "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>",
779// g.Name, rawX, rawY, rawZ);
780
781 float x = Convert.ToSingle(rawX);
782 float y = Convert.ToSingle(rawY);
783 float z = Convert.ToSingle(rawZ);
784 veclist.Add(new Vector3(x, y, z));
741 } 785 }
742 item.Owner = remoteClient.AgentId; 786 }
743
744 AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
745 787
746 SceneObjectGroup group = null; 788 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment))
789 return null;
790 SceneObjectPart rootPart = group.RootPart;
791 for (int i = 0; i < objlist.Count; i++)
792 {
793 group = objlist[i];
747 794
748 if (rezAsset != null) 795// Vector3 storedPosition = group.AbsolutePosition;
796 if (group.UUID == UUID.Zero)
749 { 797 {
750 UUID itemId = UUID.Zero; 798 m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3");
751 799 }
752 // If we have permission to copy then link the rezzed object back to the user inventory
753 // item that it came from. This allows us to enable 'save object to inventory'
754 if (!m_Scene.Permissions.BypassPermissions())
755 {
756 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
757 {
758 itemId = item.ID;
759 }
760 }
761 else
762 {
763 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
764 {
765 // Brave new fullperm world
766 itemId = item.ID;
767 }
768 }
769
770 if (item.ID == UUID.Zero)
771 {
772 m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 2");
773 }
774
775 string xmlData = Utils.BytesToString(rezAsset.Data);
776 List<SceneObjectGroup> objlist =
777 new List<SceneObjectGroup>();
778 List<Vector3> veclist = new List<Vector3>();
779
780 XmlDocument doc = new XmlDocument();
781 doc.LoadXml(xmlData);
782 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
783 if (e == null || attachment) // Single
784 {
785 SceneObjectGroup g =
786 SceneObjectSerializer.FromOriginalXmlFormat(
787 itemId, xmlData);
788 objlist.Add(g);
789 veclist.Add(new Vector3(0, 0, 0));
790
791 float offsetHeight = 0;
792 pos = m_Scene.GetNewRezLocation(
793 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
794 BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false);
795 pos.Z += offsetHeight;
796 }
797 else
798 {
799 XmlElement coll = (XmlElement)e;
800 float bx = Convert.ToSingle(coll.GetAttribute("x"));
801 float by = Convert.ToSingle(coll.GetAttribute("y"));
802 float bz = Convert.ToSingle(coll.GetAttribute("z"));
803 Vector3 bbox = new Vector3(bx, by, bz);
804
805 pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
806 RayTargetID, Quaternion.Identity,
807 BypassRayCast, bRayEndIsIntersection, true,
808 bbox, false);
809
810 pos -= bbox / 2;
811
812 XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
813 foreach (XmlNode n in groups)
814 {
815 SceneObjectGroup g =
816 SceneObjectSerializer.FromOriginalXmlFormat(
817 itemId, n.OuterXml);
818 objlist.Add(g);
819 XmlElement el = (XmlElement)n;
820 float x = Convert.ToSingle(el.GetAttribute("offsetx"));
821 float y = Convert.ToSingle(el.GetAttribute("offsety"));
822 float z = Convert.ToSingle(el.GetAttribute("offsetz"));
823 veclist.Add(new Vector3(x, y, z));
824 }
825 }
826 800
827 int primcount = 0; 801 foreach (SceneObjectPart part in group.Parts)
828 foreach (SceneObjectGroup g in objlist) 802 {
829 primcount += g.PrimCount; 803 // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
804 part.LastOwnerID = part.OwnerID;
805 part.OwnerID = remoteClient.AgentId;
806 }
830 807
831 if (!m_Scene.Permissions.CanRezObject( 808 if (!attachment)
832 primcount, remoteClient.AgentId, pos) 809 {
833 && !attachment) 810 // If it's rezzed in world, select it. Much easier to
811 // find small items.
812 //
813 foreach (SceneObjectPart part in group.Parts)
834 { 814 {
835 // The client operates in no fail mode. It will 815 part.CreateSelected = true;
836 // have already removed the item from the folder
837 // if it's no copy.
838 // Put it back if it's not an attachment
839 //
840 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
841 remoteClient.SendBulkUpdateInventory(item);
842 return null;
843 } 816 }
817 }
844 818
845 for (int i = 0 ; i < objlist.Count ; i++ ) 819 group.ResetIDs();
846 {
847 group = objlist[i];
848
849 Vector3 storedPosition = group.AbsolutePosition;
850 if (group.UUID == UUID.Zero)
851 {
852 m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3");
853 }
854 group.RootPart.FromFolderID = item.Folder;
855 820
856 // If it's rezzed in world, select it. Much easier to 821 if (attachment)
857 // find small items. 822 {
858 // 823 group.RootPart.Flags |= PrimFlags.Phantom;
859 if (!attachment) 824 group.IsAttachment = true;
860 { 825 }
861 group.RootPart.CreateSelected = true;
862 foreach (SceneObjectPart child in group.Parts)
863 child.CreateSelected = true;
864 }
865
866 group.ResetIDs();
867 826
868 if (attachment) 827 // If we're rezzing an attachment then don't ask
869 { 828 // AddNewSceneObject() to update the client since
870 group.RootPart.Flags |= PrimFlags.Phantom; 829 // we'll be doing that later on. Scheduling more than
871 group.RootPart.IsAttachment = true; 830 // one full update during the attachment
872 831 // process causes some clients to fail to display the
873 // If we're rezzing an attachment then don't ask 832 // attachment properly.
874 // AddNewSceneObject() to update the client since 833 m_Scene.AddNewSceneObject(group, true, false);
875 // we'll be doing that later on. Scheduling more 834
876 // than one full update during the attachment 835 // if attachment we set it's asset id so object updates
877 // process causes some clients to fail to display 836 // can reflect that, if not, we set it's position in world.
878 // the attachment properly. 837 if (!attachment)
879 // Also, don't persist attachments. 838 {
880 m_Scene.AddNewSceneObject(group, false, false); 839 group.ScheduleGroupForFullUpdate();
881 }
882 else
883 {
884 m_Scene.AddNewSceneObject(group, true, false);
885 }
886 840
887 // if attachment we set it's asset id so object updates 841 group.AbsolutePosition = pos + veclist[i];
888 // can reflect that, if not, we set it's position in world. 842 }
889 if (!attachment)
890 {
891 group.ScheduleGroupForFullUpdate();
892
893 group.AbsolutePosition = pos + veclist[i];
894 }
895 else
896 {
897 group.SetFromItemID(itemID);
898 }
899 843
900 SceneObjectPart rootPart = null; 844 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
901 845
902 try 846 if (!attachment)
903 { 847 {
904 rootPart = group.GetChildPart(group.UUID); 848 if (rootPart.Shape.PCode == (byte)PCode.Prim)
905 } 849 group.ClearPartAttachmentData();
906 catch (NullReferenceException)
907 {
908 string isAttachment = "";
909 850
910 if (attachment) 851 // Fire on_rez
911 isAttachment = " Object was an attachment"; 852 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
853 rootPart.ParentGroup.ResumeScripts();
912 854
913 m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); 855 rootPart.ScheduleFullUpdate();
914 } 856 }
915 857
916 // Since renaming the item in the inventory does not 858// m_log.DebugFormat(
917 // affect the name stored in the serialization, transfer 859// "[InventoryAccessModule]: Rezzed {0} {1} {2} for {3}",
918 // the correct name from the inventory to the 860// group.Name, group.LocalId, group.UUID, remoteClient.Name);
919 // object itself before we rez. 861 }
920 // On coalesced objects, do the first one
921 if (((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) || i == 0)
922 {
923 rootPart.Name = item.Name;
924 rootPart.Description = item.Description;
925 }
926 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
927 {
928 rootPart.ObjectSaleType = item.SaleType;
929 rootPart.SalePrice = item.SalePrice;
930 }
931 862
932 group.SetGroup(remoteClient.ActiveGroupId, remoteClient); 863 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
933 // TODO: Remove the magic number badness 864 // TODO: Remove the magic number badness
865 if (item != null)
866 DoPostRezWhenFromItem(item, attachment);
934 867
935 if ((rootPart.OwnerID != item.Owner) || 868 if ((rootPart.OwnerID != item.Owner) ||
936 (item.CurrentPermissions & 16) != 0 || // Magic number 869 (item.CurrentPermissions & 16) != 0 || // Magic number
937 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) 870 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
938 { 871 {
939 //Need to kill the for sale here 872 //Need to kill the for sale here
940 rootPart.ObjectSaleType = 0; 873 rootPart.ObjectSaleType = 0;
941 rootPart.SalePrice = 10; 874 rootPart.SalePrice = 10;
942
943 if (m_Scene.Permissions.PropagatePermissions())
944 {
945 foreach (SceneObjectPart part in group.Parts)
946 {
947 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
948 {
949 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
950 part.EveryoneMask = item.EveryOnePermissions;
951 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
952 part.NextOwnerMask = item.NextPermissions;
953 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
954 part.GroupMask = item.GroupPermissions;
955 }
956 }
957
958 foreach (SceneObjectPart part in group.Parts)
959 {
960 part.LastOwnerID = part.OwnerID;
961 part.OwnerID = item.Owner;
962 part.Inventory.ChangeInventoryOwner(item.Owner);
963 }
964
965 group.ApplyNextOwnerPermissions();
966 }
967 }
968 875
969 foreach (SceneObjectPart part in group.Parts) 876 if (m_Scene.Permissions.PropagatePermissions())
877 {
878 foreach (SceneObjectPart part in group.Parts)
879 {
880 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
970 { 881 {
971 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) 882 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
972 part.EveryoneMask = item.EveryOnePermissions; 883 part.EveryoneMask = item.EveryOnePermissions;
@@ -975,48 +886,182 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
975 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) 886 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
976 part.GroupMask = item.GroupPermissions; 887 part.GroupMask = item.GroupPermissions;
977 } 888 }
889 }
978 890
979 rootPart.TrimPermissions(); 891 foreach (SceneObjectPart part in group.Parts)
892 {
893 part.LastOwnerID = part.OwnerID;
894 part.OwnerID = item.Owner;
895 part.Inventory.ChangeInventoryOwner(item.Owner);
896 }
980 897
981 if (!attachment) 898 group.ApplyNextOwnerPermissions();
982 { 899 }
983 if (group.RootPart.Shape.PCode == (byte)PCode.Prim) 900 }
984 { 901 foreach (SceneObjectPart part in group.Parts)
985 // Save attachment data 902 {
986 group.RootPart.AttachPoint = group.RootPart.Shape.State; 903 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
987 group.RootPart.AttachOffset = storedPosition; 904 part.EveryoneMask = item.EveryOnePermissions;
905 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
906 part.NextOwnerMask = item.NextPermissions;
907 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
908 part.GroupMask = item.GroupPermissions;
909 }
988 910
989 group.ClearPartAttachmentData(); 911 if ((rootPart.OwnerID != item.Owner) ||
990 } 912 (item.CurrentPermissions & 16) != 0 || // Magic number
991 913 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
992 // Fire on_rez 914 {
993 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); 915 //Need to kill the for sale here
994 rootPart.ParentGroup.ResumeScripts(); 916 rootPart.ObjectSaleType = 0;
917 rootPart.SalePrice = 10;
918 }
995 919
996 rootPart.ScheduleFullUpdate(); 920 return group;
997 } 921 }
998 } 922
923 /// <summary>
924 /// Do pre-rez processing when the object comes from an item.
925 /// </summary>
926 /// <param name="remoteClient"></param>
927 /// <param name="item"></param>
928 /// <param name="objlist"></param>
929 /// <param name="pos"></param>
930 /// <param name="isAttachment"></param>
931 /// <returns>true if we can processed with rezzing, false if we need to abort</returns>
932 private bool DoPreRezWhenFromItem(
933 IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, Vector3 pos, bool isAttachment)
934 {
935 UUID fromUserInventoryItemId = UUID.Zero;
936
937 // If we have permission to copy then link the rezzed object back to the user inventory
938 // item that it came from. This allows us to enable 'save object to inventory'
939 if (!m_Scene.Permissions.BypassPermissions())
940 {
941 if ((item.CurrentPermissions & (uint)PermissionMask.Copy)
942 == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
943 {
944 fromUserInventoryItemId = item.ID;
945 }
946 }
947 else
948 {
949 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
950 {
951 // Brave new fullperm world
952 fromUserInventoryItemId = item.ID;
953 }
954 }
955
956 int primcount = 0;
957 foreach (SceneObjectGroup g in objlist)
958 primcount += g.PrimCount;
959
960 if (!m_Scene.Permissions.CanRezObject(
961 primcount, remoteClient.AgentId, pos)
962 && !isAttachment)
963 {
964 // The client operates in no fail mode. It will
965 // have already removed the item from the folder
966 // if it's no copy.
967 // Put it back if it's not an attachment
968 //
969 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
970 remoteClient.SendBulkUpdateInventory(item);
971
972 return false;
973 }
974
975 for (int i = 0; i < objlist.Count; i++)
976 {
977 SceneObjectGroup so = objlist[i];
978 SceneObjectPart rootPart = so.RootPart;
999 979
1000 if (!m_Scene.Permissions.BypassPermissions()) 980 // Since renaming the item in the inventory does not
981 // affect the name stored in the serialization, transfer
982 // the correct name from the inventory to the
983 // object itself before we rez.
984 //
985 // Only do these for the first object if we are rezzing a coalescence.
986 if (i == 0)
987 {
988 rootPart.Name = item.Name;
989 rootPart.Description = item.Description;
990 rootPart.ObjectSaleType = item.SaleType;
991 rootPart.SalePrice = item.SalePrice;
992 }
993
994 rootPart.FromFolderID = item.Folder;
995
996 if ((rootPart.OwnerID != item.Owner) ||
997 (item.CurrentPermissions & 16) != 0)
998 {
999 //Need to kill the for sale here
1000 rootPart.ObjectSaleType = 0;
1001 rootPart.SalePrice = 10;
1002
1003 if (m_Scene.Permissions.PropagatePermissions())
1001 { 1004 {
1002 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 1005 foreach (SceneObjectPart part in so.Parts)
1003 { 1006 {
1004 // If this is done on attachments, no 1007 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
1005 // copy ones will be lost, so avoid it
1006 //
1007 if (!attachment)
1008 { 1008 {
1009 List<UUID> uuids = new List<UUID>(); 1009 part.EveryoneMask = item.EveryOnePermissions;
1010 uuids.Add(item.ID); 1010 part.NextOwnerMask = item.NextPermissions;
1011 m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
1012 } 1011 }
1012 part.GroupMask = 0; // DO NOT propagate here
1013 } 1013 }
1014
1015 so.ApplyNextOwnerPermissions();
1014 } 1016 }
1015 } 1017 }
1016 return group; 1018
1019 foreach (SceneObjectPart part in so.Parts)
1020 {
1021 part.FromUserInventoryItemID = fromUserInventoryItemId;
1022
1023 if ((part.OwnerID != item.Owner) ||
1024 (item.CurrentPermissions & 16) != 0)
1025 {
1026 part.Inventory.ChangeInventoryOwner(item.Owner);
1027 part.GroupMask = 0; // DO NOT propagate here
1028 }
1029
1030 part.EveryoneMask = item.EveryOnePermissions;
1031 part.NextOwnerMask = item.NextPermissions;
1032 }
1033
1034 rootPart.TrimPermissions();
1035
1036 if (isAttachment)
1037 so.SetFromItemID(item.ID);
1017 } 1038 }
1018 1039
1019 return null; 1040 return true;
1041 }
1042
1043 /// <summary>
1044 /// Do post-rez processing when the object comes from an item.
1045 /// </summary>
1046 /// <param name="item"></param>
1047 /// <param name="isAttachment"></param>
1048 private void DoPostRezWhenFromItem(InventoryItemBase item, bool isAttachment)
1049 {
1050 if (!m_Scene.Permissions.BypassPermissions())
1051 {
1052 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1053 {
1054 // If this is done on attachments, no
1055 // copy ones will be lost, so avoid it
1056 //
1057 if (!isAttachment)
1058 {
1059 List<UUID> uuids = new List<UUID>();
1060 uuids.Add(item.ID);
1061 m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
1062 }
1063 }
1064 }
1020 } 1065 }
1021 1066
1022 protected void AddUserData(SceneObjectGroup sog) 1067 protected void AddUserData(SceneObjectGroup sog)
@@ -1033,11 +1078,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1033 public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) 1078 public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID)
1034 { 1079 {
1035 InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID); 1080 InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID);
1081
1036 if (assetRequestItem == null) 1082 if (assetRequestItem == null)
1037 { 1083 {
1038 ILibraryService lib = m_Scene.RequestModuleInterface<ILibraryService>(); 1084 ILibraryService lib = m_Scene.RequestModuleInterface<ILibraryService>();
1085
1039 if (lib != null) 1086 if (lib != null)
1040 assetRequestItem = lib.LibraryRootFolder.FindItem(itemID); 1087 assetRequestItem = lib.LibraryRootFolder.FindItem(itemID);
1088
1041 if (assetRequestItem == null) 1089 if (assetRequestItem == null)
1042 return false; 1090 return false;
1043 } 1091 }
@@ -1068,6 +1116,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1068 m_log.WarnFormat( 1116 m_log.WarnFormat(
1069 "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", 1117 "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}",
1070 Name, requestID, itemID, assetRequestItem.AssetID); 1118 Name, requestID, itemID, assetRequestItem.AssetID);
1119
1071 return false; 1120 return false;
1072 } 1121 }
1073 1122
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
index 733ad25..e74310c 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
@@ -65,8 +65,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
65 config.AddConfig("Modules"); 65 config.AddConfig("Modules");
66 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); 66 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
67 67
68 m_scene = SceneSetupHelpers.SetupScene(); 68 m_scene = SceneHelpers.SetupScene();
69 SceneSetupHelpers.SetupSceneModules(m_scene, config, m_iam); 69 SceneHelpers.SetupSceneModules(m_scene, config, m_iam);
70 70
71 // Create user 71 // Create user
72 string userFirstName = "Jock"; 72 string userFirstName = "Jock";
@@ -82,14 +82,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
82 [Test] 82 [Test]
83 public void TestRezCoalescedObject() 83 public void TestRezCoalescedObject()
84 { 84 {
85 TestHelper.InMethod(); 85 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 86// log4net.Config.XmlConfigurator.Configure();
87 87
88 // Create asset 88 // Create asset
89 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20); 89 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20);
90 object1.AbsolutePosition = new Vector3(15, 30, 45); 90 object1.AbsolutePosition = new Vector3(15, 30, 45);
91 91
92 SceneObjectGroup object2 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40); 92 SceneObjectGroup object2 = SceneHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40);
93 object2.AbsolutePosition = new Vector3(25, 50, 75); 93 object2.AbsolutePosition = new Vector3(25, 50, 75);
94 94
95 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2); 95 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2);
@@ -138,11 +138,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
138 [Test] 138 [Test]
139 public void TestRezObject() 139 public void TestRezObject()
140 { 140 {
141 TestHelper.InMethod(); 141 TestHelpers.InMethod();
142// log4net.Config.XmlConfigurator.Configure(); 142// log4net.Config.XmlConfigurator.Configure();
143 143
144 // Create asset 144 // Create asset
145 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40); 145 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40);
146 146
147 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 147 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
148 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 148 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index d570608..3155ce7 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -185,6 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
185 archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); 185 archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false);
186 archread.Execute(); 186 archread.Execute();
187 } 187 }
188
188 foreach (InventoryNodeBase node in nodes) 189 foreach (InventoryNodeBase node in nodes)
189 FixPerms(node); 190 FixPerms(node);
190 } 191 }
@@ -197,18 +198,19 @@ namespace OpenSim.Region.CoreModules.Framework.Library
197 archread.Close(); 198 archread.Close();
198 } 199 }
199 } 200 }
200
201 } 201 }
202 202
203 private void FixPerms(InventoryNodeBase node) 203 private void FixPerms(InventoryNodeBase node)
204 { 204 {
205 m_log.DebugFormat("[LIBRARY MODULE]: Fixing perms for {0} {1}", node.Name, node.ID);
206
205 if (node is InventoryItemBase) 207 if (node is InventoryItemBase)
206 { 208 {
207 InventoryItemBase item = (InventoryItemBase)node; 209 InventoryItemBase item = (InventoryItemBase)node;
208 item.BasePermissions = 0x7FFFFFFF; 210 item.BasePermissions = (uint)PermissionMask.All;
209 item.EveryOnePermissions = 0x7FFFFFFF; 211 item.EveryOnePermissions = (uint)PermissionMask.All - (uint)PermissionMask.Modify;
210 item.CurrentPermissions = 0x7FFFFFFF; 212 item.CurrentPermissions = (uint)PermissionMask.All;
211 item.NextPermissions = 0x7FFFFFFF; 213 item.NextPermissions = (uint)PermissionMask.All;
212 } 214 }
213 } 215 }
214 216
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index f15f8f6..b5cbcbb 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -68,7 +68,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
68 { 68 {
69 m_scene = scene; 69 m_scene = scene;
70 70
71
72 m_scene.AddCommand(this, "monitor report", 71 m_scene.AddCommand(this, "monitor report",
73 "monitor report", 72 "monitor report",
74 "Returns a variety of statistics about the current region and/or simulator", 73 "Returns a variety of statistics about the current region and/or simulator",
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 27eb178..bef0d69 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -87,8 +87,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
87 "Show the bindings between user UUIDs and user names", 87 "Show the bindings between user UUIDs and user names",
88 String.Empty, 88 String.Empty,
89 HandleShowUsers); 89 HandleShowUsers);
90
91
92 } 90 }
93 91
94 public bool IsSharedModule 92 public bool IsSharedModule
@@ -186,7 +184,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
186 } 184 }
187 } 185 }
188 186
189
190 private string[] GetUserNames(UUID uuid) 187 private string[] GetUserNames(UUID uuid)
191 { 188 {
192 string[] returnstring = new string[2]; 189 string[] returnstring = new string[2];
@@ -292,6 +289,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
292 return userID.ToString(); 289 return userID.ToString();
293 } 290 }
294 291
292 public void AddUser(UUID uuid, string first, string last)
293 {
294 if (m_UserCache.ContainsKey(uuid))
295 return;
296
297 UserData user = new UserData();
298 user.Id = uuid;
299 user.FirstName = first;
300 user.LastName = last;
301 // user.ProfileURL = we should initialize this to the default
302
303 AddUserInternal(user);
304 }
305
306 public void AddUser(UUID uuid, string first, string last, string profileURL)
307 {
308 AddUser(uuid, profileURL + ";" + first + " " + last);
309 }
310
295 public void AddUser(UUID id, string creatorData) 311 public void AddUser(UUID id, string creatorData)
296 { 312 {
297 if (m_UserCache.ContainsKey(id)) 313 if (m_UserCache.ContainsKey(id))
@@ -299,18 +315,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
299 315
300// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, craetorData {1}", id, creatorData); 316// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, craetorData {1}", id, creatorData);
301 317
302 UserData user = new UserData();
303 user.Id = id;
304 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id); 318 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id);
305 319
306 if (account != null) 320 if (account != null)
307 { 321 {
308 user.FirstName = account.FirstName; 322 AddUser(id, account.FirstName, account.LastName);
309 user.LastName = account.LastName;
310 // user.ProfileURL = we should initialize this to the default
311 } 323 }
312 else 324 else
313 { 325 {
326 UserData user = new UserData();
327 user.Id = id;
328
314 if (creatorData != null && creatorData != string.Empty) 329 if (creatorData != null && creatorData != string.Empty)
315 { 330 {
316 //creatorData = <endpoint>;<name> 331 //creatorData = <endpoint>;<name>
@@ -338,17 +353,19 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
338 user.FirstName = "Unknown"; 353 user.FirstName = "Unknown";
339 user.LastName = "User"; 354 user.LastName = "User";
340 } 355 }
341 }
342 356
343 lock (m_UserCache) 357 AddUserInternal(user);
344 m_UserCache[id] = user; 358 }
345
346 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL);
347 } 359 }
348 360
349 public void AddUser(UUID uuid, string first, string last, string profileURL) 361 void AddUserInternal(UserData user)
350 { 362 {
351 AddUser(uuid, profileURL + ";" + first + " " + last); 363 lock (m_UserCache)
364 m_UserCache[user.Id] = user;
365
366// m_log.DebugFormat(
367// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
368// user.Id, user.FirstName, user.LastName, user.HomeURL);
352 } 369 }
353 370
354 //public void AddUser(UUID uuid, string userData) 371 //public void AddUser(UUID uuid, string userData)
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index d647e71..a14a84b 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -282,6 +282,94 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
282 } 282 }
283 } 283 }
284 284
285 /// <summary>
286 /// Delivers the message to a scene entity.
287 /// </summary>
288 /// <param name='target'>
289 /// Target.
290 /// </param>
291 /// <param name='channel'>
292 /// Channel.
293 /// </param>
294 /// <param name='name'>
295 /// Name.
296 /// </param>
297 /// <param name='id'>
298 /// Identifier.
299 /// </param>
300 /// <param name='msg'>
301 /// Message.
302 /// </param>
303 public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error)
304 {
305 error = null;
306 // Is id an avatar?
307 ScenePresence sp = m_scene.GetScenePresence(target);
308
309 if (sp != null)
310 {
311 // Send message to avatar
312 if (channel == 0)
313 {
314 m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, pos, name, id, false);
315 }
316
317 List<SceneObjectGroup> attachments = sp.GetAttachments();
318
319 if (attachments.Count == 0)
320 return true;
321
322 // Get uuid of attachments
323 List<UUID> targets = new List<UUID>();
324 foreach (SceneObjectGroup sog in attachments)
325 {
326 if (!sog.IsDeleted)
327 targets.Add(sog.UUID);
328 }
329
330 // Need to check each attachment
331 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
332 {
333 if (li.GetHostID().Equals(id))
334 continue;
335
336 if (m_scene.GetSceneObjectPart(li.GetHostID()) == null)
337 continue;
338
339 if (targets.Contains(li.GetHostID()))
340 QueueMessage(new ListenerInfo(li, name, id, msg));
341 }
342
343 return true;
344 }
345
346 // Need to toss an error here
347 if (channel == 0)
348 {
349 error = "Cannot use llRegionSayTo to message objects on channel 0";
350 return false;
351 }
352
353 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
354 {
355 // Dont process if this message is from yourself!
356 if (li.GetHostID().Equals(id))
357 continue;
358
359 SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID());
360 if (sPart == null)
361 continue;
362
363 if ( li.GetHostID().Equals(target))
364 {
365 QueueMessage(new ListenerInfo(li, name, id, msg));
366 break;
367 }
368 }
369
370 return true;
371 }
372
285 protected void QueueMessage(ListenerInfo li) 373 protected void QueueMessage(ListenerInfo li)
286 { 374 {
287 lock (m_pending.SyncRoot) 375 lock (m_pending.SyncRoot)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs
index b570155..e5af1f4 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs
@@ -48,7 +48,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
48 private static bool m_Enabled = false; 48 private static bool m_Enabled = false;
49 49
50 private IConfigSource m_Config; 50 private IConfigSource m_Config;
51 bool m_Registered = false;
52 51
53 #region IRegionModule interface 52 #region IRegionModule interface
54 53
@@ -64,9 +63,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
64 m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled"); 63 m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled");
65 new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService"); 64 new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService");
66 } 65 }
67
68 } 66 }
69
70 } 67 }
71 68
72 public void PostInitialise() 69 public void PostInitialise()
@@ -106,6 +103,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
106 } 103 }
107 104
108 #endregion 105 #endregion
109
110 } 106 }
111} 107}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
index 51d1d59..cc5d061 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
@@ -129,15 +129,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
129 m_Cache = null; 129 m_Cache = null;
130 } 130 }
131 131
132 m_log.InfoFormat("[LOCAL ASSET SERVICES CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName); 132 m_log.DebugFormat(
133 "[LOCAL ASSET SERVICES CONNECTOR]: Enabled connector for region {0}", scene.RegionInfo.RegionName);
133 134
134 if (m_Cache != null) 135 if (m_Cache != null)
135 { 136 {
136 m_log.InfoFormat("[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); 137 m_log.DebugFormat(
138 "[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset caching for region {0}",
139 scene.RegionInfo.RegionName);
137 } 140 }
138 else 141 else
139 { 142 {
140 // Short-circuit directly to storage layer 143 // Short-circuit directly to storage layer. This ends up storing temporary and local assets.
141 // 144 //
142 scene.UnregisterModuleInterface<IAssetService>(this); 145 scene.UnregisterModuleInterface<IAssetService>(this);
143 scene.RegisterModuleInterface<IAssetService>(m_AssetService); 146 scene.RegisterModuleInterface<IAssetService>(m_AssetService);
@@ -246,9 +249,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
246 m_Cache.Cache(asset); 249 m_Cache.Cache(asset);
247 250
248 if (asset.Temporary || asset.Local) 251 if (asset.Temporary || asset.Local)
252 {
253// m_log.DebugFormat(
254// "[LOCAL ASSET SERVICE CONNECTOR]: Returning asset {0} {1} without querying database since status Temporary = {2}, Local = {3}",
255// asset.Name, asset.ID, asset.Temporary, asset.Local);
256
249 return asset.ID; 257 return asset.ID;
250 258 }
251 return m_AssetService.Store(asset); 259 else
260 {
261// m_log.DebugFormat(
262// "[LOCAL ASSET SERVICE CONNECTOR]: Passing {0} {1} on to asset service for storage, status Temporary = {2}, Local = {3}",
263// asset.Name, asset.ID, asset.Temporary, asset.Local);
264
265 return m_AssetService.Store(asset);
266 }
252 } 267 }
253 268
254 public bool UpdateContent(string id, byte[] data) 269 public bool UpdateContent(string id, byte[] data)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
index 85a1ac3..18a7177 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
@@ -39,8 +39,7 @@ using OpenMetaverse;
39 39
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization 40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
41{ 41{
42 public class LocalAuthorizationServicesConnector : 42 public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService
43 ISharedRegionModule, IAuthorizationService
44 { 43 {
45 private static readonly ILog m_log = 44 private static readonly ILog m_log =
46 LogManager.GetLogger( 45 LogManager.GetLogger(
@@ -127,15 +126,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
127 if (!m_Enabled) 126 if (!m_Enabled)
128 return; 127 return;
129 128
130 m_log.InfoFormat("[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", scene.RegionInfo.RegionName); 129 m_log.InfoFormat(
131 130 "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}",
132 131 scene.RegionInfo.RegionName);
133 } 132 }
134 133
135 public bool IsAuthorizedForRegion(string userID, string regionID, out string message) 134 public bool IsAuthorizedForRegion(
135 string userID, string firstName, string lastName, string regionID, out string message)
136 { 136 {
137 return m_AuthorizationService.IsAuthorizedForRegion(userID, regionID, out message); 137 return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message);
138 } 138 }
139
140 } 139 }
141} 140} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
index 66994fa..003324f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
@@ -117,9 +117,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
117 117
118 } 118 }
119 119
120 public bool IsAuthorizedForRegion(string userID, string regionID, out string message) 120 public bool IsAuthorizedForRegion(
121 string userID, string firstName, string lastName, string regionID, out string message)
121 { 122 {
122 m_log.InfoFormat("[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID); 123 m_log.InfoFormat(
124 "[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID);
123 125
124 bool isAuthorized = true; 126 bool isAuthorized = true;
125 message = String.Empty; 127 message = String.Empty;
@@ -140,17 +142,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
140 if (scene != null) 142 if (scene != null)
141 { 143 {
142 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID)); 144 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID));
143 isAuthorized = IsAuthorizedForRegion(userID, account.FirstName, account.LastName, 145
144 account.Email, scene.RegionInfo.RegionName, regionID, out message); 146 isAuthorized
147 = IsAuthorizedForRegion(
148 userID, firstName, lastName, account.Email, scene.RegionInfo.RegionName, regionID, out message);
145 } 149 }
146 else 150 else
147 { 151 {
148 m_log.ErrorFormat("[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0} ",regionID); 152 m_log.ErrorFormat(
153 "[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0}",
154 regionID);
149 } 155 }
150 156
151
152 return isAuthorized; 157 return isAuthorized;
153
154 } 158 }
155 } 159 }
156} 160} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
index 150a4d5..cd7d6bc 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
@@ -55,19 +55,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
55 config.Configs["Modules"].Set("GridServices", "LocalGridServicesConnector"); 55 config.Configs["Modules"].Set("GridServices", "LocalGridServicesConnector");
56 config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Services.GridService.dll:GridService"); 56 config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Services.GridService.dll:GridService");
57 config.Configs["GridService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); 57 config.Configs["GridService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
58 config.Configs["GridService"].Set("Region_Test_Region_1", "DefaultRegion"); 58 config.Configs["GridService"].Set("Region_Test_Region_1", "DefaultRegion");
59 config.Configs["GridService"].Set("Region_Test_Region_2", "FallbackRegion"); 59 config.Configs["GridService"].Set("Region_Test_Region_2", "FallbackRegion");
60 config.Configs["GridService"].Set("Region_Test_Region_3", "FallbackRegion"); 60 config.Configs["GridService"].Set("Region_Test_Region_3", "FallbackRegion");
61 config.Configs["GridService"].Set("Region_Other_Region_4", "FallbackRegion"); 61 config.Configs["GridService"].Set("Region_Other_Region_4", "FallbackRegion");
62 62
63 m_LocalConnector = new LocalGridServicesConnector(config); 63 m_LocalConnector = new LocalGridServicesConnector(config);
64 } 64 }
65 65
66 /// <summary> 66 /// <summary>
67 /// Test saving a V0.2 OpenSim Region Archive. 67 /// Test region registration.
68 /// </summary> 68 /// </summary>
69 [Test] 69 [Test]
70 public void TestRegisterRegionV0_2() 70 public void TestRegisterRegion()
71 { 71 {
72 SetUp(); 72 SetUp();
73 73
@@ -123,11 +123,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
123 m_LocalConnector.RegisterRegion(UUID.Zero, r1); 123 m_LocalConnector.RegisterRegion(UUID.Zero, r1);
124 124
125 GridRegion result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test"); 125 GridRegion result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test");
126 Assert.IsNull(result, "Retrieved GetRegionByName \"Test\" is not null");
127
128 result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test Region 1");
126 Assert.IsNotNull(result, "Retrieved GetRegionByName is null"); 129 Assert.IsNotNull(result, "Retrieved GetRegionByName is null");
127 Assert.That(result.RegionName, Is.EqualTo("Test Region 1"), "Retrieved region's name does not match"); 130 Assert.That(result.RegionName, Is.EqualTo("Test Region 1"), "Retrieved region's name does not match");
128 131
129 m_LocalConnector.RegisterRegion(UUID.Zero, r2); 132 m_LocalConnector.RegisterRegion(UUID.Zero, r2);
130 m_LocalConnector.RegisterRegion(UUID.Zero, r3); 133 m_LocalConnector.RegisterRegion(UUID.Zero, r3);
131 m_LocalConnector.RegisterRegion(UUID.Zero, r4); 134 m_LocalConnector.RegisterRegion(UUID.Zero, r4);
132 135
133 result = m_LocalConnector.GetRegionByUUID(UUID.Zero, new UUID(1)); 136 result = m_LocalConnector.GetRegionByUUID(UUID.Zero, new UUID(1));
@@ -152,38 +155,38 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
152 Assert.IsNotNull(results, "Retrieved GetRegionRange collection is null"); 155 Assert.IsNotNull(results, "Retrieved GetRegionRange collection is null");
153 Assert.That(results.Count, Is.EqualTo(2), "Retrieved neighbour collection is not the number expected"); 156 Assert.That(results.Count, Is.EqualTo(2), "Retrieved neighbour collection is not the number expected");
154 157
155 results = m_LocalConnector.GetDefaultRegions(UUID.Zero); 158 results = m_LocalConnector.GetDefaultRegions(UUID.Zero);
156 Assert.IsNotNull(results, "Retrieved GetDefaultRegions collection is null"); 159 Assert.IsNotNull(results, "Retrieved GetDefaultRegions collection is null");
157 Assert.That(results.Count, Is.EqualTo(1), "Retrieved default regions collection has not the expected size"); 160 Assert.That(results.Count, Is.EqualTo(1), "Retrieved default regions collection has not the expected size");
158 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(1)), "Retrieved default region's UUID does not match"); 161 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(1)), "Retrieved default region's UUID does not match");
159 162
160 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r1.RegionLocX, r1.RegionLocY); 163 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r1.RegionLocX, r1.RegionLocY);
161 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 1 is null"); 164 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 1 is null");
162 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 1 has not the expected size"); 165 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 1 has not the expected size");
163 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions for default region are not in the expected order 2-4-3"); 166 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions for default region are not in the expected order 2-4-3");
164 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions for default region are not in the expected order 2-4-3"); 167 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions for default region are not in the expected order 2-4-3");
165 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions for default region are not in the expected order 2-4-3"); 168 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions for default region are not in the expected order 2-4-3");
166 169
167 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r2.RegionLocX, r2.RegionLocY); 170 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r2.RegionLocX, r2.RegionLocY);
168 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 2 is null"); 171 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 2 is null");
169 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 2 has not the expected size"); 172 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 2 has not the expected size");
170 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 2-4-3"); 173 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 2-4-3");
171 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 2-4-3"); 174 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 2-4-3");
172 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 2-4-3"); 175 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 2-4-3");
173 176
174 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r3.RegionLocX, r3.RegionLocY); 177 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r3.RegionLocX, r3.RegionLocY);
175 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 3 is null"); 178 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 3 is null");
176 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 3 has not the expected size"); 179 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 3 has not the expected size");
177 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 3-4-2"); 180 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 3-4-2");
178 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 3-4-2"); 181 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 3-4-2");
179 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 3-4-2"); 182 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 3-4-2");
180 183
181 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r4.RegionLocX, r4.RegionLocY); 184 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r4.RegionLocX, r4.RegionLocY);
182 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 4 is null"); 185 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 4 is null");
183 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 4 has not the expected size"); 186 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 4 has not the expected size");
184 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 4-3-2"); 187 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 4-3-2");
185 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 4-3-2"); 188 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 4-3-2");
186 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 4-3-2"); 189 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 4-3-2");
187 190
188 results = m_LocalConnector.GetHyperlinks(UUID.Zero); 191 results = m_LocalConnector.GetHyperlinks(UUID.Zero);
189 Assert.IsNotNull(results, "Retrieved GetHyperlinks list is null"); 192 Assert.IsNotNull(results, "Retrieved GetHyperlinks list is null");
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs
index 6543845..4cf62ec 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs
@@ -66,7 +66,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
66 public void OnMakeRootAgent(ScenePresence sp) 66 public void OnMakeRootAgent(ScenePresence sp)
67 { 67 {
68// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName); 68// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
69 m_GridUserService.SetLastPosition(sp.UUID.ToString(), UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); 69
70 if (sp.PresenceType != PresenceType.Npc)
71 m_GridUserService.SetLastPosition(
72 sp.UUID.ToString(), UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
70 } 73 }
71 74
72 public void OnNewClient(IClientAPI client) 75 public void OnNewClient(IClientAPI client)
@@ -93,7 +96,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
93 lookat = ((ScenePresence)sp).Lookat; 96 lookat = ((ScenePresence)sp).Lookat;
94 } 97 }
95 } 98 }
96 m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); 99
100// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
97 m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat); 101 m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat);
98 } 102 }
99 103
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index 698fd56..0d121ed 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -64,7 +64,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
64 get 64 get
65 { 65 {
66 if (m_UserManagement == null) 66 if (m_UserManagement == null)
67 {
67 m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>(); 68 m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>();
69
70 if (m_UserManagement == null)
71 m_log.ErrorFormat(
72 "[HG INVENTORY CONNECTOR]: Could not retrieve IUserManagement module from {0}",
73 m_Scenes[0].RegionInfo.RegionName);
74 }
75
68 return m_UserManagement; 76 return m_UserManagement;
69 } 77 }
70 } 78 }
@@ -140,8 +148,29 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
140 148
141 scene.RegisterModuleInterface<IInventoryService>(this); 149 scene.RegisterModuleInterface<IInventoryService>(this);
142 150
143 scene.EventManager.OnClientClosed += OnClientClosed; 151 if (m_Scenes.Count == 1)
152 {
153 // FIXME: The local connector needs the scene to extract the UserManager. However, it's not enabled so
154 // we can't just add the region. But this approach is super-messy.
155 if (m_LocalGridInventoryService is RemoteXInventoryServicesConnector)
156 {
157 m_log.DebugFormat(
158 "[HG INVENTORY BROKER]: Manually setting scene in RemoteXInventoryServicesConnector to {0}",
159 scene.RegionInfo.RegionName);
160
161 ((RemoteXInventoryServicesConnector)m_LocalGridInventoryService).Scene = scene;
162 }
163 else if (m_LocalGridInventoryService is LocalInventoryServicesConnector)
164 {
165 m_log.DebugFormat(
166 "[HG INVENTORY BROKER]: Manually setting scene in LocalInventoryServicesConnector to {0}",
167 scene.RegionInfo.RegionName);
168
169 ((LocalInventoryServicesConnector)m_LocalGridInventoryService).Scene = scene;
170 }
144 171
172 scene.EventManager.OnClientClosed += OnClientClosed;
173 }
145 } 174 }
146 175
147 public void RemoveRegion(Scene scene) 176 public void RemoveRegion(Scene scene)
@@ -211,11 +240,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
211 return; 240 return;
212 } 241 }
213 } 242 }
214 else 243// else
215 { 244// {
216 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: User {0} does not have InventoryServerURI. OH NOES!", userID); 245// m_log.DebugFormat("[HG INVENTORY CONNECTOR]: User {0} does not have InventoryServerURI. OH NOES!", userID);
217 return; 246// return;
218 } 247// }
219 } 248 }
220 } 249 }
221 if (sp == null) 250 if (sp == null)
@@ -323,7 +352,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
323 352
324 } 353 }
325 354
326 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) 355 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
327 { 356 {
328 //m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID); 357 //m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID);
329 358
@@ -338,7 +367,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
338 367
339 } 368 }
340 369
341 public bool AddFolder(InventoryFolderBase folder) 370 public bool AddFolder(InventoryFolderBase folder)
342 { 371 {
343 if (folder == null) 372 if (folder == null)
344 return false; 373 return false;
@@ -355,7 +384,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
355 return connector.AddFolder(folder); 384 return connector.AddFolder(folder);
356 } 385 }
357 386
358 public bool UpdateFolder(InventoryFolderBase folder) 387 public bool UpdateFolder(InventoryFolderBase folder)
359 { 388 {
360 if (folder == null) 389 if (folder == null)
361 return false; 390 return false;
@@ -372,7 +401,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
372 return connector.UpdateFolder(folder); 401 return connector.UpdateFolder(folder);
373 } 402 }
374 403
375 public bool DeleteFolders(UUID ownerID, List<UUID> folderIDs) 404 public bool DeleteFolders(UUID ownerID, List<UUID> folderIDs)
376 { 405 {
377 if (folderIDs == null) 406 if (folderIDs == null)
378 return false; 407 return false;
@@ -391,7 +420,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
391 return connector.DeleteFolders(ownerID, folderIDs); 420 return connector.DeleteFolders(ownerID, folderIDs);
392 } 421 }
393 422
394 public bool MoveFolder(InventoryFolderBase folder) 423 public bool MoveFolder(InventoryFolderBase folder)
395 { 424 {
396 if (folder == null) 425 if (folder == null)
397 return false; 426 return false;
@@ -408,7 +437,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
408 return connector.MoveFolder(folder); 437 return connector.MoveFolder(folder);
409 } 438 }
410 439
411 public bool PurgeFolder(InventoryFolderBase folder) 440 public bool PurgeFolder(InventoryFolderBase folder)
412 { 441 {
413 if (folder == null) 442 if (folder == null)
414 return false; 443 return false;
@@ -442,7 +471,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
442 return connector.AddItem(item); 471 return connector.AddItem(item);
443 } 472 }
444 473
445 public bool UpdateItem(InventoryItemBase item) 474 public bool UpdateItem(InventoryItemBase item)
446 { 475 {
447 if (item == null) 476 if (item == null)
448 return false; 477 return false;
@@ -459,7 +488,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
459 return connector.UpdateItem(item); 488 return connector.UpdateItem(item);
460 } 489 }
461 490
462 public bool MoveItems(UUID ownerID, List<InventoryItemBase> items) 491 public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
463 { 492 {
464 if (items == null) 493 if (items == null)
465 return false; 494 return false;
@@ -478,7 +507,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
478 return connector.MoveItems(ownerID, items); 507 return connector.MoveItems(ownerID, items);
479 } 508 }
480 509
481 public bool DeleteItems(UUID ownerID, List<UUID> itemIDs) 510 public bool DeleteItems(UUID ownerID, List<UUID> itemIDs)
482 { 511 {
483 //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Delete {0} items for user {1}", itemIDs.Count, ownerID); 512 //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Delete {0} items for user {1}", itemIDs.Count, ownerID);
484 513
@@ -497,7 +526,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
497 return connector.DeleteItems(ownerID, itemIDs); 526 return connector.DeleteItems(ownerID, itemIDs);
498 } 527 }
499 528
500 public InventoryItemBase GetItem(InventoryItemBase item) 529 public InventoryItemBase GetItem(InventoryItemBase item)
501 { 530 {
502 if (item == null) 531 if (item == null)
503 return null; 532 return null;
@@ -513,7 +542,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
513 return connector.GetItem(item); 542 return connector.GetItem(item);
514 } 543 }
515 544
516 public InventoryFolderBase GetFolder(InventoryFolderBase folder) 545 public InventoryFolderBase GetFolder(InventoryFolderBase folder)
517 { 546 {
518 if (folder == null) 547 if (folder == null)
519 return null; 548 return null;
@@ -530,17 +559,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
530 return connector.GetFolder(folder); 559 return connector.GetFolder(folder);
531 } 560 }
532 561
533 public bool HasInventoryForUser(UUID userID) 562 public bool HasInventoryForUser(UUID userID)
534 { 563 {
535 return false; 564 return false;
536 } 565 }
537 566
538 public List<InventoryItemBase> GetActiveGestures(UUID userId) 567 public List<InventoryItemBase> GetActiveGestures(UUID userId)
539 { 568 {
540 return new List<InventoryItemBase>(); 569 return new List<InventoryItemBase>();
541 } 570 }
542 571
543 public int GetAssetPermissions(UUID userID, UUID assetID) 572 public int GetAssetPermissions(UUID userID, UUID assetID)
544 { 573 {
545 //m_log.Debug("[HG INVENTORY CONNECTOR]: GetAssetPermissions " + assetID); 574 //m_log.Debug("[HG INVENTORY CONNECTOR]: GetAssetPermissions " + assetID);
546 575
@@ -572,14 +601,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
572 string connectorType = new HeloServicesConnector(url).Helo(); 601 string connectorType = new HeloServicesConnector(url).Helo();
573 m_log.DebugFormat("[HG INVENTORY SERVICE]: HELO returned {0}", connectorType); 602 m_log.DebugFormat("[HG INVENTORY SERVICE]: HELO returned {0}", connectorType);
574 if (connectorType == "opensim-simian") 603 if (connectorType == "opensim-simian")
604 {
575 connector = new SimianInventoryServiceConnector(url); 605 connector = new SimianInventoryServiceConnector(url);
606 }
576 else 607 else
577 connector = new RemoteXInventoryServicesConnector(url); 608 {
609 RemoteXInventoryServicesConnector rxisc = new RemoteXInventoryServicesConnector(url);
610 rxisc.Scene = m_Scenes[0];
611 connector = rxisc;
612 }
613
578 m_connectors.Add(url, connector); 614 m_connectors.Add(url, connector);
579 } 615 }
580 } 616 }
617
581 return connector; 618 return connector;
582 } 619 }
583
584 } 620 }
585} 621} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index 0c57618..1c83f8e 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -47,9 +47,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
47 LogManager.GetLogger( 47 LogManager.GetLogger(
48 MethodBase.GetCurrentMethod().DeclaringType); 48 MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 private IInventoryService m_InventoryService; 50 /// <summary>
51 /// Scene used by this module. This currently needs to be publicly settable for HGInventoryBroker.
52 /// </summary>
53 public Scene Scene { get; set; }
51 54
52 private Scene m_Scene; 55 private IInventoryService m_InventoryService;
53 56
54 private IUserManagement m_UserManager; 57 private IUserManagement m_UserManager;
55 private IUserManagement UserManager 58 private IUserManagement UserManager
@@ -58,7 +61,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
58 { 61 {
59 if (m_UserManager == null) 62 if (m_UserManager == null)
60 { 63 {
61 m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>(); 64 m_UserManager = Scene.RequestModuleInterface<IUserManagement>();
62 } 65 }
63 return m_UserManager; 66 return m_UserManager;
64 } 67 }
@@ -131,8 +134,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
131 134
132 scene.RegisterModuleInterface<IInventoryService>(this); 135 scene.RegisterModuleInterface<IInventoryService>(this);
133 136
134 if (m_Scene == null) 137 if (Scene == null)
135 m_Scene = scene; 138 Scene = scene;
136 } 139 }
137 140
138 public void RemoveRegion(Scene scene) 141 public void RemoveRegion(Scene scene)
@@ -185,8 +188,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
185 Util.FireAndForget(delegate 188 Util.FireAndForget(delegate
186 { 189 {
187 if (UserManager != null) 190 if (UserManager != null)
188 foreach (InventoryItemBase item in invCol.Items) 191 {
192 // Protect ourselves against the caller subsequently modifying the items list
193 foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
189 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); 194 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
195 }
190 }); 196 });
191 197
192 return invCol; 198 return invCol;
@@ -280,7 +286,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
280 { 286 {
281// m_log.DebugFormat("[LOCAL INVENTORY SERVICES CONNECTOR]: Requesting inventory item {0}", item.ID); 287// m_log.DebugFormat("[LOCAL INVENTORY SERVICES CONNECTOR]: Requesting inventory item {0}", item.ID);
282 288
283 UUID requestedItemId = item.ID; 289// UUID requestedItemId = item.ID;
284 290
285 item = m_InventoryService.GetItem(item); 291 item = m_InventoryService.GetItem(item);
286 292
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index 8f1f257..c9c716c 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -45,19 +45,30 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
45 private static readonly ILog m_log = 45 private static readonly ILog m_log =
46 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 /// <summary>
49 /// Scene used by this module. This currently needs to be publicly settable for HGInventoryBroker.
50 /// </summary>
51 public Scene Scene { get; set; }
52
48 private bool m_Enabled = false; 53 private bool m_Enabled = false;
49 private Scene m_Scene; 54 private Scene m_Scene;
50 private XInventoryServicesConnector m_RemoteConnector; 55 private XInventoryServicesConnector m_RemoteConnector;
51 56
52 private IUserManagement m_UserManager; 57 private IUserManagement m_UserManager;
53 private IUserManagement UserManager 58 public IUserManagement UserManager
54 { 59 {
55 get 60 get
56 { 61 {
57 if (m_UserManager == null) 62 if (m_UserManager == null)
58 { 63 {
59 m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>(); 64 m_UserManager = Scene.RequestModuleInterface<IUserManagement>();
65
66 if (m_UserManager == null)
67 m_log.ErrorFormat(
68 "[XINVENTORY CONNECTOR]: Could not retrieve IUserManagement module from {0}",
69 Scene.RegionInfo.RegionName);
60 } 70 }
71
61 return m_UserManager; 72 return m_UserManager;
62 } 73 }
63 } 74 }
@@ -86,12 +97,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
86 Init(source); 97 Init(source);
87 } 98 }
88 99
89 protected void Init(IConfigSource source) 100 protected void Init(IConfigSource source)
90 { 101 {
91 m_RemoteConnector = new XInventoryServicesConnector(source); 102 m_RemoteConnector = new XInventoryServicesConnector(source);
92 } 103 }
93 104
94
95 #region ISharedRegionModule 105 #region ISharedRegionModule
96 106
97 public void Initialise(IConfigSource source) 107 public void Initialise(IConfigSource source)
@@ -128,15 +138,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
128 138
129 scene.RegisterModuleInterface<IInventoryService>(this); 139 scene.RegisterModuleInterface<IInventoryService>(this);
130 140
131 if (m_Scene == null) 141 if (Scene == null)
132 m_Scene = scene; 142 Scene = scene;
133 } 143 }
134 144
135 public void RemoveRegion(Scene scene) 145 public void RemoveRegion(Scene scene)
136 { 146 {
137 if (!m_Enabled) 147 if (!m_Enabled)
138 return; 148 return;
139
140 } 149 }
141 150
142 public void RegionLoaded(Scene scene) 151 public void RegionLoaded(Scene scene)
@@ -181,14 +190,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
181 return m_RemoteConnector.GetFolderForType(userID, type); 190 return m_RemoteConnector.GetFolderForType(userID, type);
182 } 191 }
183 192
184 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 193 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
185 { 194 {
186 InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); 195 InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
187 Util.FireAndForget(delegate 196 Util.FireAndForget(delegate
188 { 197 {
189 if (UserManager != null) 198 if (UserManager != null)
190 foreach (InventoryItemBase item in invCol.Items) 199 {
200 // Protect ourselves against the caller subsequently modifying the items list
201 foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
191 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); 202 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
203 }
192 }); 204 });
193 205
194 return invCol; 206 return invCol;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index e224670..6d3ace9 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -61,7 +61,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
61 private bool m_enabled = false; 61 private bool m_enabled = false;
62 private IMapImageService m_MapService; 62 private IMapImageService m_MapService;
63 63
64 private string m_serverUrl = String.Empty;
65 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); 64 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
66 65
67 private int m_refreshtime = 0; 66 private int m_refreshtime = 0;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
index fa5b873..e2e383f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
@@ -39,7 +39,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
39{ 39{
40 public class PresenceDetector 40 public class PresenceDetector
41 { 41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 43
44 private IPresenceService m_PresenceService; 44 private IPresenceService m_PresenceService;
45 private Scene m_aScene; 45 private Scene m_aScene;
@@ -94,7 +94,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
94 } 94 }
95 } 95 }
96 96
97 m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); 97// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
98 m_PresenceService.LogoutAgent(client.SessionId); 98 m_PresenceService.LogoutAgent(client.SessionId);
99 } 99 }
100 100
diff --git a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
index c355b13..2399134 100644
--- a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
+++ b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
@@ -129,14 +129,12 @@ namespace OpenSim.Region.CoreModules.World
129 switch (cmd[1]) 129 switch (cmd[1])
130 { 130 {
131 case "enable": 131 case "enable":
132 if (scene.LoginsDisabled)
133 MainConsole.Instance.Output(String.Format("Enabling logins for region {0}", scene.RegionInfo.RegionName));
134 scene.LoginsDisabled = false; 132 scene.LoginsDisabled = false;
133 MainConsole.Instance.Output(String.Format("Logins are enabled for region {0}", scene.RegionInfo.RegionName));
135 break; 134 break;
136 case "disable": 135 case "disable":
137 if (!scene.LoginsDisabled)
138 MainConsole.Instance.Output(String.Format("Disabling logins for region {0}", scene.RegionInfo.RegionName));
139 scene.LoginsDisabled = true; 136 scene.LoginsDisabled = true;
137 MainConsole.Instance.Output(String.Format("Logins are disabled for region {0}", scene.RegionInfo.RegionName));
140 break; 138 break;
141 case "status": 139 case "status":
142 if (scene.LoginsDisabled) 140 if (scene.LoginsDisabled)
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index f85a917..238863e 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -284,8 +284,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
284 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 284 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
285 285
286 // And zap any troublesome sit target information 286 // And zap any troublesome sit target information
287 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); 287// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
288 part.SitTargetPosition = new Vector3(0, 0, 0); 288// part.SitTargetPosition = new Vector3(0, 0, 0);
289 289
290 // Fix ownership/creator of inventory items 290 // Fix ownership/creator of inventory items
291 // Not doing so results in inventory items 291 // Not doing so results in inventory items
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index 10a83ee..b895afe 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -127,6 +127,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
127 127
128 EntityBase[] entities = m_scene.GetEntities(); 128 EntityBase[] entities = m_scene.GetEntities();
129 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 129 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
130
131 string checkPermissions = null;
132 int numObjectsSkippedPermissions = 0;
133 Object temp;
134 if (options.TryGetValue("checkPermissions", out temp))
135 checkPermissions = (string)temp;
130 136
131 // Filter entities so that we only have scene objects. 137 // Filter entities so that we only have scene objects.
132 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods 138 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
@@ -136,9 +142,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
136 if (entity is SceneObjectGroup) 142 if (entity is SceneObjectGroup)
137 { 143 {
138 SceneObjectGroup sceneObject = (SceneObjectGroup)entity; 144 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
139 145
140 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) 146 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
141 sceneObjects.Add((SceneObjectGroup)entity); 147 {
148 if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions))
149 {
150 // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR.
151 ++numObjectsSkippedPermissions;
152 }
153 else
154 {
155 sceneObjects.Add(sceneObject);
156 }
157 }
142 } 158 }
143 } 159 }
144 160
@@ -159,7 +175,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
159 { 175 {
160 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); 176 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
161 } 177 }
162 178
179 if (numObjectsSkippedPermissions > 0)
180 {
181 m_log.DebugFormat(
182 "[ARCHIVER]: {0} scene objects skipped due to lack of permissions",
183 numObjectsSkippedPermissions);
184 }
185
163 // Make sure that we also request terrain texture assets 186 // Make sure that we also request terrain texture assets
164 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; 187 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
165 188
@@ -211,6 +234,83 @@ namespace OpenSim.Region.CoreModules.World.Archiver
211 } 234 }
212 235
213 /// <summary> 236 /// <summary>
237 /// Checks whether the user has permission to export an object group to an OAR.
238 /// </summary>
239 /// <param name="user">The user</param>
240 /// <param name="objGroup">The object group</param>
241 /// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param>
242 /// <returns>Whether the user is allowed to export the object to an OAR</returns>
243 private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions)
244 {
245 if (checkPermissions == null)
246 return true;
247
248 IPermissionsModule module = m_scene.RequestModuleInterface<IPermissionsModule>();
249 if (module == null)
250 return true; // this shouldn't happen
251
252 // Check whether the user is permitted to export all of the parts in the SOG. If any
253 // part can't be exported then the entire SOG can't be exported.
254
255 bool permitted = true;
256 //int primNumber = 1;
257
258 foreach (SceneObjectPart obj in objGroup.Parts)
259 {
260 uint perm;
261 PermissionClass permissionClass = module.GetPermissionClass(user, obj);
262 switch (permissionClass)
263 {
264 case PermissionClass.Owner:
265 perm = obj.BaseMask;
266 break;
267 case PermissionClass.Group:
268 perm = obj.GroupMask | obj.EveryoneMask;
269 break;
270 case PermissionClass.Everyone:
271 default:
272 perm = obj.EveryoneMask;
273 break;
274 }
275
276 bool canCopy = (perm & (uint)PermissionMask.Copy) != 0;
277 bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0;
278
279 // Special case: if Everyone can copy the object then this implies it can also be
280 // Transferred.
281 // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask
282 // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer
283 // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied.
284 if (permissionClass != PermissionClass.Owner)
285 {
286 canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0;
287 }
288
289
290 bool partPermitted = true;
291 if (checkPermissions.Contains("C") && !canCopy)
292 partPermitted = false;
293 if (checkPermissions.Contains("T") && !canTransfer)
294 partPermitted = false;
295
296 //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount);
297 //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}",
298 // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask,
299 // permissionClass, checkPermissions, canCopy, canTransfer, permitted);
300
301 if (!partPermitted)
302 {
303 permitted = false;
304 break;
305 }
306
307 //++primNumber;
308 }
309
310 return permitted;
311 }
312
313 /// <summary>
214 /// Create the control file for the most up to date archive 314 /// Create the control file for the most up to date archive
215 /// </summary> 315 /// </summary>
216 /// <returns></returns> 316 /// <returns></returns>
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index 08eb80c..f44a3ba 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -128,6 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
128// ops.Add("v|version=", delegate(string v) { options["version"] = v; }); 128// ops.Add("v|version=", delegate(string v) { options["version"] = v; });
129 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); 129 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
130 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); 130 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
131 ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
131 132
132 List<string> mainParams = ops.Parse(cmdparams); 133 List<string> mainParams = ops.Parse(cmdparams);
133 134
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 6ba3459..e798e5e 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -68,8 +68,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
68 SerialiserModule serialiserModule = new SerialiserModule(); 68 SerialiserModule serialiserModule = new SerialiserModule();
69 TerrainModule terrainModule = new TerrainModule(); 69 TerrainModule terrainModule = new TerrainModule();
70 70
71 m_scene = SceneSetupHelpers.SetupScene(); 71 m_scene = SceneHelpers.SetupScene();
72 SceneSetupHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); 72 SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule);
73 } 73 }
74 74
75 private void LoadCompleted(Guid requestId, string errorMessage) 75 private void LoadCompleted(Guid requestId, string errorMessage)
@@ -125,7 +125,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
125 [Test] 125 [Test]
126 public void TestSaveOar() 126 public void TestSaveOar()
127 { 127 {
128 TestHelper.InMethod(); 128 TestHelpers.InMethod();
129// log4net.Config.XmlConfigurator.Configure(); 129// log4net.Config.XmlConfigurator.Configure();
130 130
131 SceneObjectPart part1 = CreateSceneObjectPart1(); 131 SceneObjectPart part1 = CreateSceneObjectPart1();
@@ -217,7 +217,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
217 [Test] 217 [Test]
218 public void TestSaveOarNoAssets() 218 public void TestSaveOarNoAssets()
219 { 219 {
220 TestHelper.InMethod(); 220 TestHelpers.InMethod();
221// log4net.Config.XmlConfigurator.Configure(); 221// log4net.Config.XmlConfigurator.Configure();
222 222
223 SceneObjectPart part1 = CreateSceneObjectPart1(); 223 SceneObjectPart part1 = CreateSceneObjectPart1();
@@ -300,7 +300,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
300 [Test] 300 [Test]
301 public void TestLoadOar() 301 public void TestLoadOar()
302 { 302 {
303 TestHelper.InMethod(); 303 TestHelpers.InMethod();
304// log4net.Config.XmlConfigurator.Configure(); 304// log4net.Config.XmlConfigurator.Configure();
305 305
306 MemoryStream archiveWriteStream = new MemoryStream(); 306 MemoryStream archiveWriteStream = new MemoryStream();
@@ -318,6 +318,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
318 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); 318 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
319 319
320 SceneObjectPart part1 = CreateSceneObjectPart1(); 320 SceneObjectPart part1 = CreateSceneObjectPart1();
321
322 part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f);
323 part1.SitTargetPosition = new Vector3(1, 2, 3);
324
321 SceneObjectGroup object1 = new SceneObjectGroup(part1); 325 SceneObjectGroup object1 = new SceneObjectGroup(part1);
322 326
323 // Let's put some inventory items into our object 327 // Let's put some inventory items into our object
@@ -390,6 +394,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
390 object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal"); 394 object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
391 Assert.That( 395 Assert.That(
392 object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal"); 396 object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
397 Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation));
398 Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition));
393 399
394 TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; 400 TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
395 Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); 401 Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
@@ -409,7 +415,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
409 [Test] 415 [Test]
410 public void TestLoadOarRegionSettings() 416 public void TestLoadOarRegionSettings()
411 { 417 {
412 TestHelper.InMethod(); 418 TestHelpers.InMethod();
413 //log4net.Config.XmlConfigurator.Configure(); 419 //log4net.Config.XmlConfigurator.Configure();
414 420
415 MemoryStream archiveWriteStream = new MemoryStream(); 421 MemoryStream archiveWriteStream = new MemoryStream();
@@ -505,7 +511,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
505 //[Test] 511 //[Test]
506 public void TestMergeOar() 512 public void TestMergeOar()
507 { 513 {
508 TestHelper.InMethod(); 514 TestHelpers.InMethod();
509 //XmlConfigurator.Configure(); 515 //XmlConfigurator.Configure();
510 516
511 MemoryStream archiveWriteStream = new MemoryStream(); 517 MemoryStream archiveWriteStream = new MemoryStream();
@@ -524,8 +530,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
524 SerialiserModule serialiserModule = new SerialiserModule(); 530 SerialiserModule serialiserModule = new SerialiserModule();
525 TerrainModule terrainModule = new TerrainModule(); 531 TerrainModule terrainModule = new TerrainModule();
526 532
527 Scene scene = SceneSetupHelpers.SetupScene(); 533 Scene scene = SceneHelpers.SetupScene();
528 SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); 534 SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
529 535
530 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); 536 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
531 537
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index b96f300..321f6b6 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -875,41 +875,35 @@ namespace OpenSim.Region.CoreModules.World.Estate
875 SceneObjectPart prt = Scene.GetSceneObjectPart(obj); 875 SceneObjectPart prt = Scene.GetSceneObjectPart(obj);
876 if (prt != null) 876 if (prt != null)
877 { 877 {
878 if (prt.ParentGroup != null) 878 SceneObjectGroup sog = prt.ParentGroup;
879 LandStatReportItem lsri = new LandStatReportItem();
880 lsri.LocationX = sog.AbsolutePosition.X;
881 lsri.LocationY = sog.AbsolutePosition.Y;
882 lsri.LocationZ = sog.AbsolutePosition.Z;
883 lsri.Score = SceneData[obj];
884 lsri.TaskID = sog.UUID;
885 lsri.TaskLocalID = sog.LocalId;
886 lsri.TaskName = sog.GetPartName(obj);
887 lsri.OwnerName = "waiting";
888 lock (uuidNameLookupList)
889 uuidNameLookupList.Add(sog.OwnerID);
890
891 if (filter.Length != 0)
879 { 892 {
880 SceneObjectGroup sog = prt.ParentGroup; 893 if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
881 if (sog != null)
882 { 894 {
883 LandStatReportItem lsri = new LandStatReportItem(); 895 }
884 lsri.LocationX = sog.AbsolutePosition.X; 896 else
885 lsri.LocationY = sog.AbsolutePosition.Y; 897 {
886 lsri.LocationZ = sog.AbsolutePosition.Z; 898 continue;
887 lsri.Score = SceneData[obj];
888 lsri.TaskID = sog.UUID;
889 lsri.TaskLocalID = sog.LocalId;
890 lsri.TaskName = sog.GetPartName(obj);
891 lsri.OwnerName = "waiting";
892 lock (uuidNameLookupList)
893 uuidNameLookupList.Add(sog.OwnerID);
894
895 if (filter.Length != 0)
896 {
897 if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
898 {
899 }
900 else
901 {
902 continue;
903 }
904 }
905
906 SceneReport.Add(lsri);
907 } 899 }
908 } 900 }
909 }
910 901
902 SceneReport.Add(lsri);
903 }
911 } 904 }
912 } 905 }
906
913 remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); 907 remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray());
914 908
915 if (uuidNameLookupList.Count > 0) 909 if (uuidNameLookupList.Count > 0)
@@ -998,6 +992,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
998 args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3; 992 args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3;
999 args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4; 993 args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4;
1000 994
995// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 1 {0} for region {1}", args.terrainDetail0, Scene.RegionInfo.RegionName);
996// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 2 {0} for region {1}", args.terrainDetail1, Scene.RegionInfo.RegionName);
997// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 3 {0} for region {1}", args.terrainDetail2, Scene.RegionInfo.RegionName);
998// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 4 {0} for region {1}", args.terrainDetail3, Scene.RegionInfo.RegionName);
999
1001 remoteClient.SendRegionHandshake(Scene.RegionInfo,args); 1000 remoteClient.SendRegionHandshake(Scene.RegionInfo,args);
1002 } 1001 }
1003 1002
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 4e7c76f..474905a 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -96,6 +96,8 @@ namespace OpenSim.Region.CoreModules.World.Land
96 96
97 // caches ExtendedLandData 97 // caches ExtendedLandData
98 private Cache parcelInfoCache; 98 private Cache parcelInfoCache;
99 private Dictionary<UUID, Vector3> forcedPosition =
100 new Dictionary<UUID, Vector3>();
99 101
100 #region INonSharedRegionModule Members 102 #region INonSharedRegionModule Members
101 103
@@ -423,17 +425,49 @@ namespace OpenSim.Region.CoreModules.World.Land
423 SendLandUpdate(avatar, false); 425 SendLandUpdate(avatar, false);
424 } 426 }
425 427
426 public void EventManagerOnSignificantClientMovement(IClientAPI remote_client) 428 public void EventManagerOnSignificantClientMovement(ScenePresence clientAvatar)
427 { 429 {
428 ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId); 430 SendLandUpdate(clientAvatar);
429 431 SendOutNearestBanLine(clientAvatar.ControllingClient);
430 if (clientAvatar != null) 432 ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
433 if (parcel != null)
431 { 434 {
432 SendLandUpdate(clientAvatar); 435 if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
433 SendOutNearestBanLine(remote_client); 436 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown)
434 ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); 437 {
435 if (parcel != null) 438 EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID,
436 EnforceBans(parcel, clientAvatar); 439 m_scene.RegionInfo.RegionID);
440 //They are going under the safety line!
441 if (!parcel.IsBannedFromLand(clientAvatar.UUID))
442 {
443 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
444 }
445 }
446 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
447 parcel.IsBannedFromLand(clientAvatar.UUID))
448 {
449 //once we've sent the message once, keep going toward the target until we are done
450 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
451 {
452 SendYouAreBannedNotice(clientAvatar);
453 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
454 }
455 }
456 else if (parcel.IsRestrictedFromLand(clientAvatar.UUID))
457 {
458 //once we've sent the message once, keep going toward the target until we are done
459 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
460 {
461 SendYouAreRestrictedNotice(clientAvatar);
462 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
463 }
464 }
465 else
466 {
467 //when we are finally in a safe place, lets release the forced position lock
468 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
469 }
470 EnforceBans(parcel, clientAvatar);
437 } 471 }
438 } 472 }
439 473
@@ -665,7 +699,7 @@ namespace OpenSim.Region.CoreModules.World.Land
665 // Corner case. If an autoreturn happens during sim startup 699 // Corner case. If an autoreturn happens during sim startup
666 // we will come here with the list uninitialized 700 // we will come here with the list uninitialized
667 // 701 //
668 int landId = m_landIDList[x, y]; 702// int landId = m_landIDList[x, y];
669 703
670// if (landId == 0) 704// if (landId == 0)
671// m_log.DebugFormat( 705// m_log.DebugFormat(
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index f466194..5122734 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Land
51 51
52 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule 52 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 private Scene m_Scene; 56 private Scene m_Scene;
57 private Dictionary<UUID, PrimCounts> m_PrimCounts = 57 private Dictionary<UUID, PrimCounts> m_PrimCounts =
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
index a3aa38d..e553ffa 100644
--- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
+++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
@@ -64,8 +64,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
64 { 64 {
65 m_pcm = new PrimCountModule(); 65 m_pcm = new PrimCountModule();
66 LandManagementModule lmm = new LandManagementModule(); 66 LandManagementModule lmm = new LandManagementModule();
67 m_scene = SceneSetupHelpers.SetupScene(); 67 m_scene = SceneHelpers.SetupScene();
68 SceneSetupHelpers.SetupSceneModules(m_scene, lmm, m_pcm); 68 SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm);
69 69
70 int xParcelDivider = (int)Constants.RegionSize - 1; 70 int xParcelDivider = (int)Constants.RegionSize - 1;
71 71
@@ -106,12 +106,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
106 [Test] 106 [Test]
107 public void TestAddOwnerObject() 107 public void TestAddOwnerObject()
108 { 108 {
109 TestHelper.InMethod(); 109 TestHelpers.InMethod();
110// log4net.Config.XmlConfigurator.Configure(); 110// log4net.Config.XmlConfigurator.Configure();
111 111
112 IPrimCounts pc = m_lo.PrimCounts; 112 IPrimCounts pc = m_lo.PrimCounts;
113 113
114 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 114 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
115 m_scene.AddNewSceneObject(sog, false); 115 m_scene.AddNewSceneObject(sog, false);
116 116
117 Assert.That(pc.Owner, Is.EqualTo(3)); 117 Assert.That(pc.Owner, Is.EqualTo(3));
@@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
124 Assert.That(pc.Simulator, Is.EqualTo(3)); 124 Assert.That(pc.Simulator, Is.EqualTo(3));
125 125
126 // Add a second object and retest 126 // Add a second object and retest
127 SceneObjectGroup sog2 = SceneSetupHelpers.CreateSceneObject(2, m_userId, "b", 0x10); 127 SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10);
128 m_scene.AddNewSceneObject(sog2, false); 128 m_scene.AddNewSceneObject(sog2, false);
129 129
130 Assert.That(pc.Owner, Is.EqualTo(5)); 130 Assert.That(pc.Owner, Is.EqualTo(5));
@@ -143,12 +143,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
143 [Test] 143 [Test]
144 public void TestCopyOwnerObject() 144 public void TestCopyOwnerObject()
145 { 145 {
146 TestHelper.InMethod(); 146 TestHelpers.InMethod();
147// log4net.Config.XmlConfigurator.Configure(); 147// log4net.Config.XmlConfigurator.Configure();
148 148
149 IPrimCounts pc = m_lo.PrimCounts; 149 IPrimCounts pc = m_lo.PrimCounts;
150 150
151 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 151 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
152 m_scene.AddNewSceneObject(sog, false); 152 m_scene.AddNewSceneObject(sog, false);
153 m_scene.SceneGraph.DuplicateObject(sog.LocalId, Vector3.Zero, 0, m_userId, UUID.Zero, Quaternion.Identity); 153 m_scene.SceneGraph.DuplicateObject(sog.LocalId, Vector3.Zero, 0, m_userId, UUID.Zero, Quaternion.Identity);
154 154
@@ -169,12 +169,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
169 [Test] 169 [Test]
170 public void TestMoveOwnerObject() 170 public void TestMoveOwnerObject()
171 { 171 {
172 TestHelper.InMethod(); 172 TestHelpers.InMethod();
173// log4net.Config.XmlConfigurator.Configure(); 173// log4net.Config.XmlConfigurator.Configure();
174 174
175 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 175 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
176 m_scene.AddNewSceneObject(sog, false); 176 m_scene.AddNewSceneObject(sog, false);
177 SceneObjectGroup sog2 = SceneSetupHelpers.CreateSceneObject(2, m_userId, "b", 0x10); 177 SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10);
178 m_scene.AddNewSceneObject(sog2, false); 178 m_scene.AddNewSceneObject(sog2, false);
179 179
180 // Move the first scene object to the eastern strip parcel 180 // Move the first scene object to the eastern strip parcel
@@ -230,13 +230,13 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
230 [Test] 230 [Test]
231 public void TestRemoveOwnerObject() 231 public void TestRemoveOwnerObject()
232 { 232 {
233 TestHelper.InMethod(); 233 TestHelpers.InMethod();
234// log4net.Config.XmlConfigurator.Configure(); 234// log4net.Config.XmlConfigurator.Configure();
235 235
236 IPrimCounts pc = m_lo.PrimCounts; 236 IPrimCounts pc = m_lo.PrimCounts;
237 237
238 m_scene.AddNewSceneObject(SceneSetupHelpers.CreateSceneObject(1, m_userId, "a", 0x1), false); 238 m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1), false);
239 SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_userId, "b", 0x10); 239 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10);
240 m_scene.AddNewSceneObject(sogToDelete, false); 240 m_scene.AddNewSceneObject(sogToDelete, false);
241 m_scene.DeleteSceneObject(sogToDelete, false); 241 m_scene.DeleteSceneObject(sogToDelete, false);
242 242
@@ -253,14 +253,14 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
253 [Test] 253 [Test]
254 public void TestAddGroupObject() 254 public void TestAddGroupObject()
255 { 255 {
256 TestHelper.InMethod(); 256 TestHelpers.InMethod();
257// log4net.Config.XmlConfigurator.Configure(); 257// log4net.Config.XmlConfigurator.Configure();
258 258
259 m_lo.DeedToGroup(m_groupId); 259 m_lo.DeedToGroup(m_groupId);
260 260
261 IPrimCounts pc = m_lo.PrimCounts; 261 IPrimCounts pc = m_lo.PrimCounts;
262 262
263 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); 263 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01);
264 sog.GroupID = m_groupId; 264 sog.GroupID = m_groupId;
265 m_scene.AddNewSceneObject(sog, false); 265 m_scene.AddNewSceneObject(sog, false);
266 266
@@ -284,18 +284,18 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
284 [Test] 284 [Test]
285 public void TestRemoveGroupObject() 285 public void TestRemoveGroupObject()
286 { 286 {
287 TestHelper.InMethod(); 287 TestHelpers.InMethod();
288// log4net.Config.XmlConfigurator.Configure(); 288// log4net.Config.XmlConfigurator.Configure();
289 289
290 m_lo.DeedToGroup(m_groupId); 290 m_lo.DeedToGroup(m_groupId);
291 291
292 IPrimCounts pc = m_lo.PrimCounts; 292 IPrimCounts pc = m_lo.PrimCounts;
293 293
294 SceneObjectGroup sogToKeep = SceneSetupHelpers.CreateSceneObject(1, m_userId, "a", 0x1); 294 SceneObjectGroup sogToKeep = SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1);
295 sogToKeep.GroupID = m_groupId; 295 sogToKeep.GroupID = m_groupId;
296 m_scene.AddNewSceneObject(sogToKeep, false); 296 m_scene.AddNewSceneObject(sogToKeep, false);
297 297
298 SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_userId, "b", 0x10); 298 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10);
299 m_scene.AddNewSceneObject(sogToDelete, false); 299 m_scene.AddNewSceneObject(sogToDelete, false);
300 m_scene.DeleteSceneObject(sogToDelete, false); 300 m_scene.DeleteSceneObject(sogToDelete, false);
301 301
@@ -313,12 +313,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
313 [Test] 313 [Test]
314 public void TestAddOthersObject() 314 public void TestAddOthersObject()
315 { 315 {
316 TestHelper.InMethod(); 316 TestHelpers.InMethod();
317// log4net.Config.XmlConfigurator.Configure(); 317// log4net.Config.XmlConfigurator.Configure();
318 318
319 IPrimCounts pc = m_lo.PrimCounts; 319 IPrimCounts pc = m_lo.PrimCounts;
320 320
321 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); 321 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01);
322 m_scene.AddNewSceneObject(sog, false); 322 m_scene.AddNewSceneObject(sog, false);
323 323
324 Assert.That(pc.Owner, Is.EqualTo(0)); 324 Assert.That(pc.Owner, Is.EqualTo(0));
@@ -334,13 +334,13 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
334 [Test] 334 [Test]
335 public void TestRemoveOthersObject() 335 public void TestRemoveOthersObject()
336 { 336 {
337 TestHelper.InMethod(); 337 TestHelpers.InMethod();
338// log4net.Config.XmlConfigurator.Configure(); 338// log4net.Config.XmlConfigurator.Configure();
339 339
340 IPrimCounts pc = m_lo.PrimCounts; 340 IPrimCounts pc = m_lo.PrimCounts;
341 341
342 m_scene.AddNewSceneObject(SceneSetupHelpers.CreateSceneObject(1, m_otherUserId, "a", 0x1), false); 342 m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_otherUserId, "a", 0x1), false);
343 SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_otherUserId, "b", 0x10); 343 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_otherUserId, "b", 0x10);
344 m_scene.AddNewSceneObject(sogToDelete, false); 344 m_scene.AddNewSceneObject(sogToDelete, false);
345 m_scene.DeleteSceneObject(sogToDelete, false); 345 m_scene.DeleteSceneObject(sogToDelete, false);
346 346
@@ -360,10 +360,10 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
360 [Test] 360 [Test]
361 public void TestTaint() 361 public void TestTaint()
362 { 362 {
363 TestHelper.InMethod(); 363 TestHelpers.InMethod();
364 IPrimCounts pc = m_lo.PrimCounts; 364 IPrimCounts pc = m_lo.PrimCounts;
365 365
366 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 366 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
367 m_scene.AddNewSceneObject(sog, false); 367 m_scene.AddNewSceneObject(sog, false);
368 368
369 m_pcm.TaintPrimCount(); 369 m_pcm.TaintPrimCount();
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
index aa14054..1d2141e 100644
--- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
+++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
@@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
173 private Bitmap fetchTexture(UUID id) 173 private Bitmap fetchTexture(UUID id)
174 { 174 {
175 AssetBase asset = m_scene.AssetService.Get(id.ToString()); 175 AssetBase asset = m_scene.AssetService.Get(id.ToString());
176 m_log.DebugFormat("Fetched texture {0}, found: {1}", id, asset != null); 176 m_log.DebugFormat("[TexturedMapTileRenderer]: Fetched texture {0}, found: {1}", id, asset != null);
177 if (asset == null) return null; 177 if (asset == null) return null;
178 178
179 ManagedImage managedImage; 179 ManagedImage managedImage;
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
index d5b7082..4326606 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
@@ -53,17 +53,17 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
53 public void SetUp() 53 public void SetUp()
54 { 54 {
55 m_module = new MoapModule(); 55 m_module = new MoapModule();
56 m_scene = SceneSetupHelpers.SetupScene(); 56 m_scene = SceneHelpers.SetupScene();
57 SceneSetupHelpers.SetupSceneModules(m_scene, m_module); 57 SceneHelpers.SetupSceneModules(m_scene, m_module);
58 } 58 }
59 59
60 [Test] 60 [Test]
61 public void TestClearMediaUrl() 61 public void TestClearMediaUrl()
62 { 62 {
63 TestHelper.InMethod(); 63 TestHelpers.InMethod();
64// log4net.Config.XmlConfigurator.Configure(); 64// log4net.Config.XmlConfigurator.Configure();
65 65
66 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(m_scene); 66 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
67 MediaEntry me = new MediaEntry(); 67 MediaEntry me = new MediaEntry();
68 68
69 m_module.SetMediaEntry(part, 1, me); 69 m_module.SetMediaEntry(part, 1, me);
@@ -84,11 +84,11 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
84 [Test] 84 [Test]
85 public void TestSetMediaUrl() 85 public void TestSetMediaUrl()
86 { 86 {
87 TestHelper.InMethod(); 87 TestHelpers.InMethod();
88 88
89 string homeUrl = "opensimulator.org"; 89 string homeUrl = "opensimulator.org";
90 90
91 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(m_scene); 91 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
92 MediaEntry me = new MediaEntry() { HomeURL = homeUrl }; 92 MediaEntry me = new MediaEntry() { HomeURL = homeUrl };
93 93
94 m_module.SetMediaEntry(part, 1, me); 94 m_module.SetMediaEntry(part, 1, me);
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index 516189f..49e3236 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
85 IClientAPI client, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice) 85 IClientAPI client, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice)
86 { 86 {
87 SceneObjectPart part = m_scene.GetSceneObjectPart(localID); 87 SceneObjectPart part = m_scene.GetSceneObjectPart(localID);
88 if (part == null || part.ParentGroup == null) 88 if (part == null)
89 return; 89 return;
90 90
91 if (part.ParentGroup.IsDeleted) 91 if (part.ParentGroup.IsDeleted)
@@ -111,9 +111,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
111 if (part == null) 111 if (part == null)
112 return false; 112 return false;
113 113
114 if (part.ParentGroup == null)
115 return false;
116
117 SceneObjectGroup group = part.ParentGroup; 114 SceneObjectGroup group = part.ParentGroup;
118 115
119 switch (saleType) 116 switch (saleType)
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 2c7843f..2e877f0 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -39,7 +39,7 @@ using OpenSim.Services.Interfaces;
39 39
40namespace OpenSim.Region.CoreModules.World.Permissions 40namespace OpenSim.Region.CoreModules.World.Permissions
41{ 41{
42 public class PermissionsModule : IRegionModule 42 public class PermissionsModule : IRegionModule, IPermissionsModule
43 { 43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 45
@@ -146,10 +146,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
146 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors); 146 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors);
147 147
148 if (m_bypassPermissions) 148 if (m_bypassPermissions)
149 m_log.Info("[PERMISSIONS]: serviceside_object_permissions = false in ini file so disabling all region service permission checks"); 149 m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks");
150 else 150 else
151 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); 151 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
152 152
153 scene.RegisterModuleInterface<IPermissionsModule>(this);
154
153 //Register functions with Scene External Checks! 155 //Register functions with Scene External Checks!
154 m_scene.Permissions.OnBypassPermissions += BypassPermissions; 156 m_scene.Permissions.OnBypassPermissions += BypassPermissions;
155 m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; 157 m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions;
@@ -574,46 +576,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
574 if (objectOwner != UUID.Zero) 576 if (objectOwner != UUID.Zero)
575 objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; 577 objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner;
576 578
577 if (m_bypassPermissions) 579 PermissionClass permissionClass = GetPermissionClass(user, task);
578 return objectOwnerMask;
579
580 // Object owners should be able to edit their own content
581 if (user == objectOwner)
582 return objectOwnerMask;
583
584 if (IsFriendWithPerms(user, objectOwner))
585 {
586 return objectOwnerMask;
587 }
588 // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
589 if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
590 {
591 return objectOwnerMask;
592 }
593
594 // Admin should be able to edit anything in the sim (including admin objects)
595 if (IsAdministrator(user))
596 {
597 return objectOwnerMask;
598 }
599 580
600 // Users should be able to edit what is over their land. 581 switch (permissionClass)
601 Vector3 taskPos = task.AbsolutePosition;
602 ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
603 if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod)
604 { 582 {
605 // Admin objects should not be editable by the above 583 case PermissionClass.Owner:
606 if (!IsAdministrator(objectOwner))
607 {
608 return objectOwnerMask; 584 return objectOwnerMask;
609 } 585 case PermissionClass.Group:
586 return objectGroupMask | objectEveryoneMask;
587 case PermissionClass.Everyone:
588 default:
589 return objectEveryoneMask;
610 } 590 }
611
612 // Group permissions
613 if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
614 return objectGroupMask | objectEveryoneMask;
615
616 return objectEveryoneMask;
617 } 591 }
618 592
619 private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) 593 private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask)
@@ -644,6 +618,47 @@ namespace OpenSim.Region.CoreModules.World.Permissions
644 return objectFlagsMask; 618 return objectFlagsMask;
645 } 619 }
646 620
621 public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj)
622 {
623 if (obj == null)
624 return PermissionClass.Everyone;
625
626 if (m_bypassPermissions)
627 return PermissionClass.Owner;
628
629 // Object owners should be able to edit their own content
630 UUID objectOwner = obj.OwnerID;
631 if (user == objectOwner)
632 return PermissionClass.Owner;
633
634 if (IsFriendWithPerms(user, objectOwner))
635 return PermissionClass.Owner;
636
637 // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
638 if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
639 return PermissionClass.Owner;
640
641 // Admin should be able to edit anything in the sim (including admin objects)
642 if (IsAdministrator(user))
643 return PermissionClass.Owner;
644
645 // Users should be able to edit what is over their land.
646 Vector3 taskPos = obj.AbsolutePosition;
647 ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
648 if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod)
649 {
650 // Admin objects should not be editable by the above
651 if (!IsAdministrator(objectOwner))
652 return PermissionClass.Owner;
653 }
654
655 // Group permissions
656 if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0))
657 return PermissionClass.Group;
658
659 return PermissionClass.Everyone;
660 }
661
647 /// <summary> 662 /// <summary>
648 /// General permissions checks for any operation involving an object. These supplement more specific checks 663 /// General permissions checks for any operation involving an object. These supplement more specific checks
649 /// implemented by callers. 664 /// implemented by callers.
@@ -1131,7 +1146,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
1131 SceneObjectPart part = scene.GetSceneObjectPart(objectID); 1146 SceneObjectPart part = scene.GetSceneObjectPart(objectID);
1132 if (part.OwnerID != moverID) 1147 if (part.OwnerID != moverID)
1133 { 1148 {
1134 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) 1149 if (!part.ParentGroup.IsDeleted)
1135 { 1150 {
1136 if (part.ParentGroup.IsAttachment) 1151 if (part.ParentGroup.IsAttachment)
1137 return false; 1152 return false;
diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
index 4f752ab..d5b585a 100644
--- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
+++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
@@ -236,14 +236,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
236 public void Init() 236 public void Init()
237 { 237 {
238 m_serialiserModule = new SerialiserModule(); 238 m_serialiserModule = new SerialiserModule();
239 m_scene = SceneSetupHelpers.SetupScene(); 239 m_scene = SceneHelpers.SetupScene();
240 SceneSetupHelpers.SetupSceneModules(m_scene, m_serialiserModule); 240 SceneHelpers.SetupSceneModules(m_scene, m_serialiserModule);
241 } 241 }
242 242
243 [Test] 243 [Test]
244 public void TestDeserializeXml() 244 public void TestDeserializeXml()
245 { 245 {
246 TestHelper.InMethod(); 246 TestHelpers.InMethod();
247 //log4net.Config.XmlConfigurator.Configure(); 247 //log4net.Config.XmlConfigurator.Configure();
248 248
249 SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(xml); 249 SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(xml);
@@ -259,7 +259,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
259 [Test] 259 [Test]
260 public void TestSerializeXml() 260 public void TestSerializeXml()
261 { 261 {
262 TestHelper.InMethod(); 262 TestHelpers.InMethod();
263 //log4net.Config.XmlConfigurator.Configure(); 263 //log4net.Config.XmlConfigurator.Configure();
264 264
265 string rpName = "My Little Donkey"; 265 string rpName = "My Little Donkey";
@@ -334,7 +334,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
334 [Test] 334 [Test]
335 public void TestDeserializeXml2() 335 public void TestDeserializeXml2()
336 { 336 {
337 TestHelper.InMethod(); 337 TestHelpers.InMethod();
338 //log4net.Config.XmlConfigurator.Configure(); 338 //log4net.Config.XmlConfigurator.Configure();
339 339
340 SceneObjectGroup so = m_serialiserModule.DeserializeGroupFromXml2(xml2); 340 SceneObjectGroup so = m_serialiserModule.DeserializeGroupFromXml2(xml2);
@@ -350,7 +350,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
350 [Test] 350 [Test]
351 public void TestSerializeXml2() 351 public void TestSerializeXml2()
352 { 352 {
353 TestHelper.InMethod(); 353 TestHelpers.InMethod();
354 //log4net.Config.XmlConfigurator.Configure(); 354 //log4net.Config.XmlConfigurator.Configure();
355 355
356 string rpName = "My Little Pony"; 356 string rpName = "My Little Pony";
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index 09c0ebb..22ffcd6 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
81 81
82 if (grp.IsAttachment) 82 if (grp.IsAttachment)
83 { 83 {
84 if (grp.GetAttachmentPoint() > 30) // HUD 84 if (grp.AttachmentPoint > 30) // HUD
85 { 85 {
86 if (sp.ControllingClient.AgentId != grp.OwnerID) 86 if (sp.ControllingClient.AgentId != grp.OwnerID)
87 return; 87 return;
@@ -115,7 +115,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
115 { 115 {
116 SceneObjectGroup grp = part.ParentGroup; 116 SceneObjectGroup grp = part.ParentGroup;
117 117
118 if (grp.IsAttachment && grp.GetAttachmentPoint() > 30) 118 if (grp.IsAttachment && grp.AttachmentPoint > 30)
119 { 119 {
120 objectID = ownerID; 120 objectID = ownerID;
121 parentID = ownerID; 121 parentID = ownerID;
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 2da6458..a93ffaa 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -84,7 +84,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
84 private ITerrainChannel m_revert; 84 private ITerrainChannel m_revert;
85 private Scene m_scene; 85 private Scene m_scene;
86 private volatile bool m_tainted; 86 private volatile bool m_tainted;
87 private readonly UndoStack<LandUndoState> m_undo = new UndoStack<LandUndoState>(5); 87 private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5);
88 88
89 #region ICommandableModule Members 89 #region ICommandableModule Members
90 90
diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
index c2ad7b8..ab8e1bf 100644
--- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
+++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
@@ -100,15 +100,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Vegetation
100 { 100 {
101 case Tree.Cypress1: 101 case Tree.Cypress1:
102 case Tree.Cypress2: 102 case Tree.Cypress2:
103 tree.Scale = new Vector3(4, 4, 10); 103 tree.Scale *= new Vector3(8, 8, 20);
104 break; 104 break;
105 105
106 // case... other tree types 106 // case... other tree types
107 // tree.Scale = new Vector3(?, ?, ?); 107 // tree.Scale *= new Vector3(?, ?, ?);
108 // break; 108 // break;
109 109
110 default: 110 default:
111 tree.Scale = new Vector3(4, 4, 4); 111 tree.Scale *= new Vector3(8, 8, 8);
112 break; 112 break;
113 } 113 }
114 } 114 }
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index ced2773..c13e9c6 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -96,16 +96,7 @@ m_log.DebugFormat("MAP NAME=({0})", mapName);
96 96
97 // try to fetch from GridServer 97 // try to fetch from GridServer
98 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); 98 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
99 if (regionInfos == null) 99 if (regionInfos.Count == 0)
100 {
101 m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?");
102 // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region
103 regionInfos = new List<GridRegion>();
104 GridRegion info = m_scene.GridService.GetRegionByName(m_scene.RegionInfo.ScopeID, mapName);
105 if (info != null)
106 regionInfos.Add(info);
107 }
108 else if (regionInfos.Count == 0)
109 remoteClient.SendAlertMessage("Hyperlink could not be established."); 100 remoteClient.SendAlertMessage("Hyperlink could not be established.");
110 101
111 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); 102 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index ca5529d9..21e3ecb 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -46,6 +46,7 @@ using OpenSim.Framework.Servers;
46using OpenSim.Framework.Servers.HttpServer; 46using OpenSim.Framework.Servers.HttpServer;
47using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.CoreModules.World.Land;
49using Caps=OpenSim.Framework.Capabilities.Caps; 50using Caps=OpenSim.Framework.Capabilities.Caps;
50using OSDArray=OpenMetaverse.StructuredData.OSDArray; 51using OSDArray=OpenMetaverse.StructuredData.OSDArray;
51using OSDMap=OpenMetaverse.StructuredData.OSDMap; 52using OSDMap=OpenMetaverse.StructuredData.OSDMap;
@@ -68,6 +69,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
68 protected Scene m_scene; 69 protected Scene m_scene;
69 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 70 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
70 private int cachedTime = 0; 71 private int cachedTime = 0;
72 private int blacklistTimeout = 10*60*1000; // 10 minutes
71 private byte[] myMapImageJPEG; 73 private byte[] myMapImageJPEG;
72 protected volatile bool m_Enabled = false; 74 protected volatile bool m_Enabled = false;
73 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>(); 75 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>();
@@ -85,6 +87,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
85 IConfig startupConfig = config.Configs["Startup"]; 87 IConfig startupConfig = config.Configs["Startup"];
86 if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap") 88 if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap")
87 m_Enabled = true; 89 m_Enabled = true;
90
91 blacklistTimeout = startupConfig.GetInt("BlacklistTimeout", 10*60) * 1000;
88 } 92 }
89 93
90 public virtual void AddRegion (Scene scene) 94 public virtual void AddRegion (Scene scene)
@@ -159,11 +163,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
159 m_scene.EventManager.OnClientClosed += ClientLoggedOut; 163 m_scene.EventManager.OnClientClosed += ClientLoggedOut;
160 m_scene.EventManager.OnMakeChildAgent += MakeChildAgent; 164 m_scene.EventManager.OnMakeChildAgent += MakeChildAgent;
161 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; 165 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent;
166 m_scene.EventManager.OnRegionUp += OnRegionUp;
167
168 StartThread(new object());
162 } 169 }
163 170
164 // this has to be called with a lock on m_scene 171 // this has to be called with a lock on m_scene
165 protected virtual void RemoveHandlers() 172 protected virtual void RemoveHandlers()
166 { 173 {
174 StopThread();
175
176 m_scene.EventManager.OnRegionUp -= OnRegionUp;
167 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; 177 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent;
168 m_scene.EventManager.OnMakeChildAgent -= MakeChildAgent; 178 m_scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
169 m_scene.EventManager.OnClientClosed -= ClientLoggedOut; 179 m_scene.EventManager.OnClientClosed -= ClientLoggedOut;
@@ -279,7 +289,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
279 /// <returns></returns> 289 /// <returns></returns>
280 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) 290 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
281 { 291 {
282 m_log.Debug("[WORLD MAP]: MapLayer Request in region: " + m_scene.RegionInfo.RegionName); 292 m_log.DebugFormat("[WORLD MAP]: MapLayer Request in region: {0}", m_scene.RegionInfo.RegionName);
283 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 293 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
284 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 294 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
285 return mapResponse; 295 return mapResponse;
@@ -321,8 +331,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
321 lock (m_rootAgents) 331 lock (m_rootAgents)
322 { 332 {
323 m_rootAgents.Remove(AgentId); 333 m_rootAgents.Remove(AgentId);
324 if (m_rootAgents.Count == 0)
325 StopThread();
326 } 334 }
327 } 335 }
328 #endregion 336 #endregion
@@ -362,6 +370,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
362 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 370 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
363 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 371 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
364 { 372 {
373// m_log.DebugFormat("[WORLD MAP]: Handle MapItem request {0} {1}", regionhandle, itemtype);
374
365 lock (m_rootAgents) 375 lock (m_rootAgents)
366 { 376 {
367 if (!m_rootAgents.Contains(remoteClient.AgentId)) 377 if (!m_rootAgents.Contains(remoteClient.AgentId))
@@ -370,7 +380,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
370 uint xstart = 0; 380 uint xstart = 0;
371 uint ystart = 0; 381 uint ystart = 0;
372 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out xstart, out ystart); 382 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out xstart, out ystart);
373 if (itemtype == 6) // we only sevice 6 right now (avatar green dots) 383 if (itemtype == 6) // Service 6 right now (MAP_ITEM_AGENTS_LOCATION; green dots)
374 { 384 {
375 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) 385 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle)
376 { 386 {
@@ -414,14 +424,57 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
414 // Remote Map Item Request 424 // Remote Map Item Request
415 425
416 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes. 426 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes.
417 // Note that we only start up a remote mapItem Request thread if there's users who could 427 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle);
418 // be making requests 428 }
419 if (!threadrunning) 429 } else if (itemtype == 7) // Service 7 (MAP_ITEM_LAND_FOR_SALE)
430 {
431 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle)
432 {
433 // Parcels
434 ILandChannel landChannel = m_scene.LandChannel;
435 List<ILandObject> parcels = landChannel.AllParcels();
436
437 // Local Map Item Request
438 List<mapItemReply> mapitems = new List<mapItemReply>();
439 mapItemReply mapitem = new mapItemReply();
440 if ((parcels != null) && (parcels.Count >= 1))
420 { 441 {
421 m_log.Warn("[WORLD MAP]: Starting new remote request thread manually. This means that AvatarEnteringParcel never fired! This needs to be fixed! Don't Mantis this, as the developers can see it in this message"); 442 foreach (ILandObject parcel_interface in parcels)
422 StartThread(new object()); 443 {
444 // Play it safe
445 if (!(parcel_interface is LandObject))
446 continue;
447
448 LandObject land = (LandObject)parcel_interface;
449 LandData parcel = land.LandData;
450
451 // Show land for sale
452 if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale)
453 {
454 Vector3 min = parcel.AABBMin;
455 Vector3 max = parcel.AABBMax;
456 float x = (min.X+max.X)/2;
457 float y = (min.Y+max.Y)/2;
458
459 mapitem = new mapItemReply();
460 mapitem.x = (uint)(xstart + x);
461 mapitem.y = (uint)(ystart + y);
462 // mapitem.z = (uint)m_scene.GetGroundHeight(x,y);
463 mapitem.id = UUID.Zero;
464 mapitem.name = parcel.Name;
465 mapitem.Extra = parcel.Area;
466 mapitem.Extra2 = parcel.SalePrice;
467 mapitems.Add(mapitem);
468 }
469 }
423 } 470 }
471 remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
472 }
473 else
474 {
475 // Remote Map Item Request
424 476
477 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes.
425 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); 478 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle);
426 } 479 }
427 } 480 }
@@ -542,6 +595,28 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
542 } 595 }
543 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); 596 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
544 } 597 }
598
599 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
600 uint itemtype = 7;
601
602 if (response.ContainsKey(itemtype.ToString()))
603 {
604 List<mapItemReply> returnitems = new List<mapItemReply>();
605 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
606 for (int i = 0; i < itemarray.Count; i++)
607 {
608 OSDMap mapitem = (OSDMap)itemarray[i];
609 mapItemReply mi = new mapItemReply();
610 mi.x = (uint)mapitem["X"].AsInteger();
611 mi.y = (uint)mapitem["Y"].AsInteger();
612 mi.id = mapitem["ID"].AsUUID();
613 mi.Extra = mapitem["Extra"].AsInteger();
614 mi.Extra2 = mapitem["Extra2"].AsInteger();
615 mi.name = mapitem["Name"].AsString();
616 returnitems.Add(mi);
617 }
618 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
619 }
545 } 620 }
546 } 621 }
547 } 622 }
@@ -589,12 +664,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
589 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 664 private OSDMap RequestMapItemsAsync(UUID id, uint flags,
590 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 665 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
591 { 666 {
667// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
668
592 string httpserver = ""; 669 string httpserver = "";
593 bool blacklisted = false; 670 bool blacklisted = false;
594 lock (m_blacklistedregions) 671 lock (m_blacklistedregions)
595 { 672 {
596 if (m_blacklistedregions.ContainsKey(regionhandle)) 673 if (m_blacklistedregions.ContainsKey(regionhandle))
597 blacklisted = true; 674 {
675 if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout))
676 {
677 m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted region {0}", regionhandle);
678
679 m_blacklistedregions.Remove(regionhandle);
680 }
681 else
682 blacklisted = true;
683 }
598 } 684 }
599 685
600 if (blacklisted) 686 if (blacklisted)
@@ -636,7 +722,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
636 lock (m_blacklistedurls) 722 lock (m_blacklistedurls)
637 { 723 {
638 if (m_blacklistedurls.ContainsKey(httpserver)) 724 if (m_blacklistedurls.ContainsKey(httpserver))
639 blacklisted = true; 725 {
726 if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout))
727 {
728 m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted URL {0}", httpserver);
729
730 m_blacklistedurls.Remove(httpserver);
731 }
732 else
733 blacklisted = true;
734 }
640 } 735 }
641 736
642 // Can't find the http server 737 // Can't find the http server
@@ -682,7 +777,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
682 mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send 777 mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send
683 os = mapitemsrequest.GetRequestStream(); 778 os = mapitemsrequest.GetRequestStream();
684 os.Write(buffer, 0, buffer.Length); //Send it 779 os.Write(buffer, 0, buffer.Length); //Send it
685 os.Close();
686 //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver); 780 //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver);
687 } 781 }
688 catch (WebException ex) 782 catch (WebException ex)
@@ -705,6 +799,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
705 responseMap["connect"] = OSD.FromBoolean(false); 799 responseMap["connect"] = OSD.FromBoolean(false);
706 return responseMap; 800 return responseMap;
707 } 801 }
802 finally
803 {
804 if (os != null)
805 os.Close();
806 }
708 807
709 string response_mapItems_reply = null; 808 string response_mapItems_reply = null;
710 { // get the response 809 { // get the response
@@ -1060,6 +1159,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1060 1159
1061 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); 1160 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart);
1062 1161
1162 // Service 6 (MAP_ITEM_AGENTS_LOCATION; green dots)
1163
1063 OSDMap responsemap = new OSDMap(); 1164 OSDMap responsemap = new OSDMap();
1064 int tc = Environment.TickCount; 1165 int tc = Environment.TickCount;
1065 if (m_scene.GetRootAgentCount() == 0) 1166 if (m_scene.GetRootAgentCount() == 0)
@@ -1092,6 +1193,60 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1092 }); 1193 });
1093 responsemap["6"] = responsearr; 1194 responsemap["6"] = responsearr;
1094 } 1195 }
1196
1197 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
1198
1199 ILandChannel landChannel = m_scene.LandChannel;
1200 List<ILandObject> parcels = landChannel.AllParcels();
1201
1202 if ((parcels == null) || (parcels.Count == 0))
1203 {
1204 OSDMap responsemapdata = new OSDMap();
1205 responsemapdata["X"] = OSD.FromInteger((int)(xstart + 1));
1206 responsemapdata["Y"] = OSD.FromInteger((int)(ystart + 1));
1207 responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
1208 responsemapdata["Name"] = OSD.FromString("");
1209 responsemapdata["Extra"] = OSD.FromInteger(0);
1210 responsemapdata["Extra2"] = OSD.FromInteger(0);
1211 OSDArray responsearr = new OSDArray();
1212 responsearr.Add(responsemapdata);
1213
1214 responsemap["7"] = responsearr;
1215 }
1216 else
1217 {
1218 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount());
1219 foreach (ILandObject parcel_interface in parcels)
1220 {
1221 // Play it safe
1222 if (!(parcel_interface is LandObject))
1223 continue;
1224
1225 LandObject land = (LandObject)parcel_interface;
1226 LandData parcel = land.LandData;
1227
1228 // Show land for sale
1229 if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale)
1230 {
1231 Vector3 min = parcel.AABBMin;
1232 Vector3 max = parcel.AABBMax;
1233 float x = (min.X+max.X)/2;
1234 float y = (min.Y+max.Y)/2;
1235
1236 OSDMap responsemapdata = new OSDMap();
1237 responsemapdata["X"] = OSD.FromInteger((int)(xstart + x));
1238 responsemapdata["Y"] = OSD.FromInteger((int)(ystart + y));
1239 // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y));
1240 responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
1241 responsemapdata["Name"] = OSD.FromString(parcel.Name);
1242 responsemapdata["Extra"] = OSD.FromInteger(parcel.Area);
1243 responsemapdata["Extra2"] = OSD.FromInteger(parcel.SalePrice);
1244 responsearr.Add(responsemapdata);
1245 }
1246 }
1247 responsemap["7"] = responsearr;
1248 }
1249
1095 return responsemap; 1250 return responsemap;
1096 } 1251 }
1097 1252
@@ -1110,14 +1265,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1110 if (data == null) 1265 if (data == null)
1111 return; 1266 return;
1112 1267
1113 UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID;
1114
1115 m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); 1268 m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE");
1116 1269
1117 m_scene.RegionInfo.RegionSettings.TerrainImageID = UUID.Random(); 1270 UUID terrainImageID = UUID.Random();
1118 1271
1119 AssetBase asset = new AssetBase( 1272 AssetBase asset = new AssetBase(
1120 m_scene.RegionInfo.RegionSettings.TerrainImageID, 1273 terrainImageID,
1121 "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(), 1274 "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(),
1122 (sbyte)AssetType.Texture, 1275 (sbyte)AssetType.Texture,
1123 m_scene.RegionInfo.RegionID.ToString()); 1276 m_scene.RegionInfo.RegionID.ToString());
@@ -1129,6 +1282,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1129 // Store the new one 1282 // Store the new one
1130 m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); 1283 m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID);
1131 m_scene.AssetService.Store(asset); 1284 m_scene.AssetService.Store(asset);
1285
1286 // Switch to the new one
1287 UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID;
1288 m_scene.RegionInfo.RegionSettings.TerrainImageID = terrainImageID;
1132 m_scene.RegionInfo.RegionSettings.Save(); 1289 m_scene.RegionInfo.RegionSettings.Save();
1133 1290
1134 // Delete the old one 1291 // Delete the old one
@@ -1138,12 +1295,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1138 1295
1139 private void MakeRootAgent(ScenePresence avatar) 1296 private void MakeRootAgent(ScenePresence avatar)
1140 { 1297 {
1141 // You may ask, why this is in a threadpool to start with..
1142 // The reason is so we don't cause the thread to freeze waiting
1143 // for the 1 second it costs to start a thread manually.
1144 if (!threadrunning)
1145 Util.FireAndForget(this.StartThread);
1146
1147 lock (m_rootAgents) 1298 lock (m_rootAgents)
1148 { 1299 {
1149 if (!m_rootAgents.Contains(avatar.UUID)) 1300 if (!m_rootAgents.Contains(avatar.UUID))
@@ -1158,8 +1309,30 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1158 lock (m_rootAgents) 1309 lock (m_rootAgents)
1159 { 1310 {
1160 m_rootAgents.Remove(avatar.UUID); 1311 m_rootAgents.Remove(avatar.UUID);
1161 if (m_rootAgents.Count == 0) 1312 }
1162 StopThread(); 1313 }
1314
1315 public void OnRegionUp(GridRegion otherRegion)
1316 {
1317 ulong regionhandle = otherRegion.RegionHandle;
1318 string httpserver = otherRegion.ServerURI + "MAP/MapItems/" + regionhandle.ToString();
1319
1320 lock (m_blacklistedregions)
1321 {
1322 if (!m_blacklistedregions.ContainsKey(regionhandle))
1323 m_blacklistedregions.Remove(regionhandle);
1324 }
1325
1326 lock (m_blacklistedurls)
1327 {
1328 if (m_blacklistedurls.ContainsKey(httpserver))
1329 m_blacklistedurls.Remove(httpserver);
1330 }
1331
1332 lock (m_cachedRegionMapItemsAddress)
1333 {
1334 if (!m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
1335 m_cachedRegionMapItemsAddress.Remove(regionhandle);
1163 } 1336 }
1164 } 1337 }
1165 1338