aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs127
-rw-r--r--OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs417
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs273
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs32
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs22
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs86
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs18
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs (renamed from OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs)149
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs194
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs (renamed from OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs)265
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs138
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs119
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs139
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs293
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs141
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs38
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs10
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs46
-rw-r--r--OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs2
-rwxr-xr-xOpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs15
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs10
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs79
-rw-r--r--OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs21
-rw-r--r--OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs14
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs8
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs67
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs35
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs20
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs317
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs129
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandChannel.cs5
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs98
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs13
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs110
-rw-r--r--OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs70
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs54
-rw-r--r--OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs39
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Sun/SunModule.cs44
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs3
-rw-r--r--OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/World/Wind/WindModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs11
65 files changed, 2653 insertions, 1193 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index 7332415..f489262 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
42 public class AssetTransactionModule : INonSharedRegionModule, 42 public class AssetTransactionModule : INonSharedRegionModule,
43 IAgentAssetTransactions 43 IAgentAssetTransactions
44 { 44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 protected Scene m_Scene; 47 protected Scene m_Scene;
48 private bool m_dumpAssetsToFile = false; 48 private bool m_dumpAssetsToFile = false;
@@ -214,9 +214,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
214 public void HandleTaskItemUpdateFromTransaction( 214 public void HandleTaskItemUpdateFromTransaction(
215 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) 215 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
216 { 216 {
217 m_log.DebugFormat( 217// m_log.DebugFormat(
218 "[ASSET TRANSACTION MODULE] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", 218// "[ASSET TRANSACTION MODULE]: Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
219 item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName); 219// item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
220 220
221 AgentAssetTransactions transactions = 221 AgentAssetTransactions transactions =
222 GetUserTransactions(remoteClient.AgentId); 222 GetUserTransactions(remoteClient.AgentId);
@@ -230,15 +230,17 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
230 /// </summary> 230 /// </summary>
231 /// <param name="remoteClient"></param> 231 /// <param name="remoteClient"></param>
232 /// <param name="assetID"></param> 232 /// <param name="assetID"></param>
233 /// <param name="transaction"></param> 233 /// <param name="transactionID"></param>
234 /// <param name="type"></param> 234 /// <param name="type"></param>
235 /// <param name="data"></param></param> 235 /// <param name="data"></param></param>
236 /// <param name="tempFile"></param> 236 /// <param name="tempFile"></param>
237 public void HandleUDPUploadRequest(IClientAPI remoteClient, 237 public void HandleUDPUploadRequest(IClientAPI remoteClient,
238 UUID assetID, UUID transaction, sbyte type, byte[] data, 238 UUID assetID, UUID transactionID, sbyte type, byte[] data,
239 bool storeLocal, bool tempFile) 239 bool storeLocal, bool tempFile)
240 { 240 {
241// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile); 241// m_log.DebugFormat(
242// "[ASSET TRANSACTION MODULE]: HandleUDPUploadRequest - assetID: {0}, transaction {1}, type {2}, storeLocal {3}, tempFile {4}, data.Length {5}",
243// assetID, transactionID, type, storeLocal, tempFile, data.Length);
242 244
243 if (((AssetType)type == AssetType.Texture || 245 if (((AssetType)type == AssetType.Texture ||
244 (AssetType)type == AssetType.Sound || 246 (AssetType)type == AssetType.Sound ||
@@ -274,8 +276,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
274 } 276 }
275 277
276 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 278 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
277 AssetXferUploader uploader = transactions.RequestXferUploader(transaction); 279 AssetXferUploader uploader = transactions.RequestXferUploader(transactionID);
278 uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); 280 uploader.StartUpload(remoteClient, assetID, transactionID, type, data, storeLocal, tempFile);
279 } 281 }
280 282
281 /// <summary> 283 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index ec388f4..08e7cb7 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -363,11 +363,11 @@ namespace OpenSim.Region.CoreModules.Asset
363 /// Try to get an asset from the file cache. 363 /// Try to get an asset from the file cache.
364 /// </summary> 364 /// </summary>
365 /// <param name="id"></param> 365 /// <param name="id"></param>
366 /// <returns></returns> 366 /// <returns>An asset retrieved from the file cache. null if there was a problem retrieving an asset.</returns>
367 private AssetBase GetFromFileCache(string id) 367 private AssetBase GetFromFileCache(string id)
368 { 368 {
369 AssetBase asset = null; 369 AssetBase asset = null;
370 370
371 string filename = GetFileName(id); 371 string filename = GetFileName(id);
372 while (File.Exists(filename)) 372 while (File.Exists(filename))
373 { 373 {
@@ -385,7 +385,7 @@ namespace OpenSim.Region.CoreModules.Asset
385 } 385 }
386 catch (System.Runtime.Serialization.SerializationException e) 386 catch (System.Runtime.Serialization.SerializationException e)
387 { 387 {
388 m_log.ErrorFormat( 388 m_log.WarnFormat(
389 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 389 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
390 filename, id, e.Message, e.StackTrace); 390 filename, id, e.Message, e.StackTrace);
391 391
@@ -407,7 +407,7 @@ namespace OpenSim.Region.CoreModules.Asset
407 } 407 }
408 catch (Exception e) 408 catch (Exception e)
409 { 409 {
410 m_log.ErrorFormat( 410 m_log.WarnFormat(
411 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 411 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
412 filename, id, e.Message, e.StackTrace); 412 filename, id, e.Message, e.StackTrace);
413 413
@@ -566,7 +566,7 @@ namespace OpenSim.Region.CoreModules.Asset
566 } 566 }
567 catch (Exception e) 567 catch (Exception e)
568 { 568 {
569 m_log.ErrorFormat( 569 m_log.WarnFormat(
570 "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}", 570 "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}",
571 id, e.Message, e.StackTrace); 571 id, e.Message, e.StackTrace);
572 } 572 }
@@ -617,29 +617,39 @@ namespace OpenSim.Region.CoreModules.Asset
617 /// <param name="purgeLine"></param> 617 /// <param name="purgeLine"></param>
618 private void CleanExpiredFiles(string dir, DateTime purgeLine) 618 private void CleanExpiredFiles(string dir, DateTime purgeLine)
619 { 619 {
620 foreach (string file in Directory.GetFiles(dir)) 620 try
621 { 621 {
622 if (File.GetLastAccessTime(file) < purgeLine) 622 foreach (string file in Directory.GetFiles(dir))
623 { 623 {
624 File.Delete(file); 624 if (File.GetLastAccessTime(file) < purgeLine)
625 {
626 File.Delete(file);
627 }
625 } 628 }
626 }
627 629
628 // Recurse into lower tiers 630 // Recurse into lower tiers
629 foreach (string subdir in Directory.GetDirectories(dir)) 631 foreach (string subdir in Directory.GetDirectories(dir))
630 { 632 {
631 CleanExpiredFiles(subdir, purgeLine); 633 CleanExpiredFiles(subdir, purgeLine);
632 } 634 }
633 635
634 // Check if a tier directory is empty, if so, delete it 636 // Check if a tier directory is empty, if so, delete it
635 int dirSize = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length; 637 int dirSize = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length;
636 if (dirSize == 0) 638 if (dirSize == 0)
637 { 639 {
638 Directory.Delete(dir); 640 Directory.Delete(dir);
641 }
642 else if (dirSize >= m_CacheWarnAt)
643 {
644 m_log.WarnFormat(
645 "[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration",
646 dir, dirSize);
647 }
639 } 648 }
640 else if (dirSize >= m_CacheWarnAt) 649 catch (Exception e)
641 { 650 {
642 m_log.WarnFormat("[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration", dir, dirSize); 651 m_log.Warn(
652 string.Format("[FLOTSAM ASSET CACHE]: Could not complete clean of expired files in {0}, exception ", dir), e);
643 } 653 }
644 } 654 }
645 655
@@ -698,7 +708,7 @@ namespace OpenSim.Region.CoreModules.Asset
698 } 708 }
699 catch (IOException e) 709 catch (IOException e)
700 { 710 {
701 m_log.ErrorFormat( 711 m_log.WarnFormat(
702 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.", 712 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.",
703 asset.ID, tempname, filename, directory, e.Message, e.StackTrace); 713 asset.ID, tempname, filename, directory, e.Message, e.StackTrace);
704 714
@@ -777,17 +787,31 @@ namespace OpenSim.Region.CoreModules.Asset
777 /// <summary> 787 /// <summary>
778 /// This notes the last time the Region had a deep asset scan performed on it. 788 /// This notes the last time the Region had a deep asset scan performed on it.
779 /// </summary> 789 /// </summary>
780 /// <param name="RegionID"></param> 790 /// <param name="regionID"></param>
781 private void StampRegionStatusFile(UUID RegionID) 791 private void StampRegionStatusFile(UUID regionID)
782 { 792 {
783 string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + RegionID.ToString() + ".fac"); 793 string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + regionID.ToString() + ".fac");
784 if (File.Exists(RegionCacheStatusFile)) 794
795 try
785 { 796 {
786 File.SetLastWriteTime(RegionCacheStatusFile, DateTime.Now); 797 if (File.Exists(RegionCacheStatusFile))
798 {
799 File.SetLastWriteTime(RegionCacheStatusFile, DateTime.Now);
800 }
801 else
802 {
803 File.WriteAllText(
804 RegionCacheStatusFile,
805 "Please do not delete this file unless you are manually clearing your Flotsam Asset Cache.");
806 }
787 } 807 }
788 else 808 catch (Exception e)
789 { 809 {
790 File.WriteAllText(RegionCacheStatusFile, "Please do not delete this file unless you are manually clearing your Flotsam Asset Cache."); 810 m_log.Warn(
811 string.Format(
812 "[FLOTSAM ASSET CACHE]: Could not stamp region status file for region {0}. Exception ",
813 regionID),
814 e);
791 } 815 }
792 } 816 }
793 817
@@ -804,32 +828,43 @@ namespace OpenSim.Region.CoreModules.Asset
804 { 828 {
805 UuidGatherer gatherer = new UuidGatherer(m_AssetService); 829 UuidGatherer gatherer = new UuidGatherer(m_AssetService);
806 830
831 HashSet<UUID> uniqueUuids = new HashSet<UUID>();
807 Dictionary<UUID, AssetType> assets = new Dictionary<UUID, AssetType>(); 832 Dictionary<UUID, AssetType> assets = new Dictionary<UUID, AssetType>();
833
808 foreach (Scene s in m_Scenes) 834 foreach (Scene s in m_Scenes)
809 { 835 {
810 StampRegionStatusFile(s.RegionInfo.RegionID); 836 StampRegionStatusFile(s.RegionInfo.RegionID);
811 837
812 s.ForEachSOG(delegate(SceneObjectGroup e) 838 s.ForEachSOG(delegate(SceneObjectGroup e)
813 { 839 {
814 gatherer.GatherAssetUuids(e, assets); 840 gatherer.GatherAssetUuids(e, assets);
815 });
816 }
817 841
818 foreach (UUID assetID in assets.Keys) 842 foreach (UUID assetID in assets.Keys)
819 { 843 {
820 string filename = GetFileName(assetID.ToString()); 844 uniqueUuids.Add(assetID);
821 845
822 if (File.Exists(filename)) 846 string filename = GetFileName(assetID.ToString());
823 { 847
824 File.SetLastAccessTime(filename, DateTime.Now); 848 if (File.Exists(filename))
825 } 849 {
826 else if (storeUncached) 850 File.SetLastAccessTime(filename, DateTime.Now);
827 { 851 }
828 m_AssetService.Get(assetID.ToString()); 852 else if (storeUncached)
829 } 853 {
854 AssetBase cachedAsset = m_AssetService.Get(assetID.ToString());
855 if (cachedAsset == null && assets[assetID] != AssetType.Unknown)
856 m_log.DebugFormat(
857 "[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets",
858 assetID, assets[assetID], e.Name, e.AbsolutePosition, s.Name);
859 }
860 }
861
862 assets.Clear();
863 });
830 } 864 }
831 865
832 return assets.Keys.Count; 866
867 return uniqueUuids.Count;
833 } 868 }
834 869
835 /// <summary> 870 /// <summary>
@@ -845,7 +880,7 @@ namespace OpenSim.Region.CoreModules.Asset
845 } 880 }
846 catch (Exception e) 881 catch (Exception e)
847 { 882 {
848 m_log.ErrorFormat( 883 m_log.WarnFormat(
849 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}", 884 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}",
850 dir, m_CacheDirectory, e.Message, e.StackTrace); 885 dir, m_CacheDirectory, e.Message, e.StackTrace);
851 } 886 }
@@ -859,7 +894,7 @@ namespace OpenSim.Region.CoreModules.Asset
859 } 894 }
860 catch (Exception e) 895 catch (Exception e)
861 { 896 {
862 m_log.ErrorFormat( 897 m_log.WarnFormat(
863 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}", 898 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}",
864 file, m_CacheDirectory, e.Message, e.StackTrace); 899 file, m_CacheDirectory, e.Message, e.StackTrace);
865 } 900 }
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
index 1c2bfd0..fd02b08 100644
--- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
+++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
@@ -47,14 +47,16 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
47 /// At the moment we're only test the in-memory part of the FlotsamAssetCache. This is a considerable weakness. 47 /// At the moment we're only test the in-memory part of the FlotsamAssetCache. This is a considerable weakness.
48 /// </summary> 48 /// </summary>
49 [TestFixture] 49 [TestFixture]
50 public class FlotsamAssetCacheTests 50 public class FlotsamAssetCacheTests : OpenSimTestCase
51 { 51 {
52 protected TestScene m_scene; 52 protected TestScene m_scene;
53 protected FlotsamAssetCache m_cache; 53 protected FlotsamAssetCache m_cache;
54 54
55 [SetUp] 55 [SetUp]
56 public void SetUp() 56 public override void SetUp()
57 { 57 {
58 base.SetUp();
59
58 IConfigSource config = new IniConfigSource(); 60 IConfigSource config = new IniConfigSource();
59 61
60 config.AddConfig("Modules"); 62 config.AddConfig("Modules");
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 7cc5092..f62512e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -256,12 +256,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
256 256
257// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); 257// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
258 258
259 List<SceneObjectGroup> attachments = sp.GetAttachments();
260
261 if (attachments.Count <= 0)
262 return;
263
264 Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>();
265
266 foreach (SceneObjectGroup so in attachments)
267 {
268 // Scripts MUST be snapshotted before the object is
269 // removed from the scene because doing otherwise will
270 // clobber the run flag
271 // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from
272 // scripts performing attachment operations at the same time. Getting object states stops the scripts.
273 scriptStates[so] = PrepareScriptInstanceForSave(so, false);
274 }
275
259 lock (sp.AttachmentsSyncLock) 276 lock (sp.AttachmentsSyncLock)
260 { 277 {
261 foreach (SceneObjectGroup so in sp.GetAttachments()) 278 foreach (SceneObjectGroup so in attachments)
262 { 279 UpdateDetachedObject(sp, so, scriptStates[so]);
263 UpdateDetachedObject(sp, so);
264 }
265 280
266 sp.ClearAttachments(); 281 sp.ClearAttachments();
267 } 282 }
@@ -289,105 +304,79 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
289 if (!Enabled) 304 if (!Enabled)
290 return false; 305 return false;
291 306
292 if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp, append)) 307 return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp, false, append);
293 {
294 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
295 return true;
296 }
297
298 return false;
299 } 308 }
300 309
301 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append) 310 /// <summary>
311 /// Internal method which actually does all the work for attaching an object.
312 /// </summary>
313 /// <returns>The object attached.</returns>
314 /// <param name='sp'></param>
315 /// <param name='group'>The object to attach.</param>
316 /// <param name='attachmentPt'></param>
317 /// <param name='silent'></param>
318 /// <param name='temp'></param>
319 /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param>
320 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool resumeScripts, bool append)
302 { 321 {
303 lock (sp.AttachmentsSyncLock)
304 {
305// m_log.DebugFormat( 322// m_log.DebugFormat(
306// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", 323// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
307// group.Name, group.LocalId, sp.Name, attachmentPt, silent); 324// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
308 325
309 if (group.GetSittingAvatarsCount() != 0) 326 if (sp.GetAttachments().Contains(group))
310 { 327 {
328// m_log.WarnFormat(
329// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
330// group.Name, group.LocalId, sp.Name, AttachmentPt);
331
332 return false;
333 }
334
335 if (group.GetSittingAvatarsCount() != 0)
336 {
311// m_log.WarnFormat( 337// m_log.WarnFormat(
312// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", 338// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it",
313// group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); 339// group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount());
314
315 return false;
316 }
317
318 if (sp.GetAttachments(attachmentPt).Contains(group))
319 {
320 // m_log.WarnFormat(
321 // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
322 // group.Name, group.LocalId, sp.Name, AttachmentPt);
323
324 return false;
325 }
326
327 Vector3 attachPos = group.AbsolutePosition;
328
329 // If the attachment point isn't the same as the one previously used
330 // set it's offset position = 0 so that it appears on the attachment point
331 // and not in a weird location somewhere unknown.
332 if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
333 {
334 attachPos = Vector3.Zero;
335 }
336
337 // AttachmentPt 0 means the client chose to 'wear' the attachment.
338 if (attachmentPt == 0)
339 {
340 // Check object for stored attachment point
341 attachmentPt = group.AttachmentPoint;
342 }
343
344 // if we still didn't find a suitable attachment point.......
345 if (attachmentPt == 0)
346 {
347 // Stick it on left hand with Zero Offset from the attachment point.
348 attachmentPt = (uint)AttachmentPoint.LeftHand;
349 attachPos = Vector3.Zero;
350 }
351
352 if (useAttachData)
353 {
354 group.RootPart.RotationOffset = group.RootPart.AttachRotation;
355 attachPos = group.RootPart.AttachOffset;
356 if (attachmentPt == 0)
357 {
358 attachmentPt = group.RootPart.AttachPoint;
359 if (attachmentPt == 0)
360 {
361 attachmentPt = (uint)AttachmentPoint.LeftHand;
362 attachPos = Vector3.Zero;
363 }
364 }
365 else if (group.RootPart.AttachPoint != attachmentPt)
366 {
367 attachPos = Vector3.Zero;
368 }
369 }
370 group.AttachmentPoint = attachmentPt;
371 group.AbsolutePosition = attachPos;
372 340
373 if (sp.PresenceType != PresenceType.Npc) 341 return false;
374 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
375
376 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
377 } 342 }
378 343
379 return true; 344 Vector3 attachPos = group.AbsolutePosition;
380 } 345
346 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
347 // be removed when that functionality is implemented in opensim
348 attachmentPt &= 0x7f;
349
350 // If the attachment point isn't the same as the one previously used
351 // set it's offset position = 0 so that it appears on the attachment point
352 // and not in a weird location somewhere unknown.
353 if (attachmentPt != (uint)AttachmentPoint.Default && attachmentPt != group.AttachmentPoint)
354 {
355 attachPos = Vector3.Zero;
356 }
357
358 // AttachmentPt 0 (default) means the client chose to 'wear' the attachment.
359 if (attachmentPt == (uint)AttachmentPoint.Default)
360 {
361 // Check object for stored attachment point
362 attachmentPt = group.AttachmentPoint;
363 }
364
365 // if we still didn't find a suitable attachment point.......
366 if (attachmentPt == 0)
367 {
368 // Stick it on left hand with Zero Offset from the attachment point.
369 attachmentPt = (uint)AttachmentPoint.LeftHand;
370 attachPos = Vector3.Zero;
371 }
381 372
382 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append)
383 {
384 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); 373 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
385 374
386 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones 375 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
387 while (attachments.Count >= 5) 376 while (attachments.Count >= 5)
388 { 377 {
389 if (attachments[0].FromItemID != UUID.Zero) 378 if (attachments[0].FromItemID != UUID.Zero)
390 DetachSingleAttachmentToInvInternal(sp, attachments[0]); 379 DetachSingleAttachmentToInv(sp, attachments[0]);
391 attachments.RemoveAt(0); 380 attachments.RemoveAt(0);
392 } 381 }
393 382
@@ -397,10 +386,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
397 foreach (SceneObjectGroup g in attachments) 386 foreach (SceneObjectGroup g in attachments)
398 { 387 {
399 if (g.FromItemID != UUID.Zero) 388 if (g.FromItemID != UUID.Zero)
400 DetachSingleAttachmentToInvInternal(sp, g); 389 DetachSingleAttachmentToInv(sp, g);
401 } 390 }
402 } 391 }
403 392
393 lock (sp.AttachmentsSyncLock)
394 {
395 group.AttachmentPoint = attachmentPt;
396 group.AbsolutePosition = attachPos;
397
398 if (sp.PresenceType != PresenceType.Npc)
399 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
400
401 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
402
403 if (resumeScripts)
404 {
405 // Fire after attach, so we don't get messy perms dialogs
406 // 4 == AttachedRez
407 group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
408 group.ResumeScripts();
409 }
410
411 // Do this last so that event listeners have access to all the effects of the attachment
412 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
413 }
414
415 return true;
416 }
417
418 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append)
419 {
404 // Add the new attachment to inventory if we don't already have it. 420 // Add the new attachment to inventory if we don't already have it.
405 if (!temp) 421 if (!temp)
406 { 422 {
@@ -423,8 +439,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
423 return null; 439 return null;
424 440
425// m_log.DebugFormat( 441// m_log.DebugFormat(
426// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", 442// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}",
427// (AttachmentPoint)AttachmentPt, itemID, sp.Name); 443// (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name);
428 444
429 bool append = (AttachmentPt & 0x80) != 0; 445 bool append = (AttachmentPt & 0x80) != 0;
430 AttachmentPt &= 0x7f; 446 AttachmentPt &= 0x7f;
@@ -464,12 +480,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
464 return; 480 return;
465 481
466 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); 482 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name);
467 lock (sp.AttachmentsSyncLock) 483
484 foreach (KeyValuePair<UUID, uint> rez in rezlist)
468 { 485 {
469 foreach (KeyValuePair<UUID, uint> rez in rezlist) 486 RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value);
470 {
471 RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value);
472 }
473 } 487 }
474 } 488 }
475 489
@@ -549,25 +563,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
549 563
550 public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) 564 public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
551 { 565 {
566 if (so.AttachedAvatar != sp.UUID)
567 {
568 m_log.WarnFormat(
569 "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}",
570 so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName);
571
572 return;
573 }
574
575// m_log.DebugFormat(
576// "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}",
577// so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name);
578
579 // Scripts MUST be snapshotted before the object is
580 // removed from the scene because doing otherwise will
581 // clobber the run flag
582 // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from
583 // scripts performing attachment operations at the same time. Getting object states stops the scripts.
584 string scriptedState = PrepareScriptInstanceForSave(so, true);
585
552 lock (sp.AttachmentsSyncLock) 586 lock (sp.AttachmentsSyncLock)
553 { 587 {
554 // Save avatar attachment information 588 // Save avatar attachment information
555// m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); 589// m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);
556 590
557 if (so.AttachedAvatar != sp.UUID)
558 {
559 m_log.WarnFormat(
560 "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}",
561 so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName);
562
563 return;
564 }
565
566 bool changed = sp.Appearance.DetachAttachment(so.FromItemID); 591 bool changed = sp.Appearance.DetachAttachment(so.FromItemID);
567 if (changed && m_scene.AvatarFactory != null) 592 if (changed && m_scene.AvatarFactory != null)
568 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); 593 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
569 594
570 DetachSingleAttachmentToInvInternal(sp, so); 595 sp.RemoveAttachment(so);
596 UpdateDetachedObject(sp, so, scriptedState);
571 } 597 }
572 } 598 }
573 599
@@ -722,15 +748,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
722 748
723 if (!silent) 749 if (!silent)
724 { 750 {
725 // Killing it here will cause the client to deselect it 751 if (so.HasPrivateAttachmentPoint)
726 // It then reappears on the avatar, deselected
727 // through the full update below
728 //
729 if (so.IsSelected)
730 {
731 m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId });
732 }
733 else if (so.HasPrivateAttachmentPoint)
734 { 752 {
735// m_log.DebugFormat( 753// m_log.DebugFormat(
736// "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", 754// "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}",
@@ -745,7 +763,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
745 }); 763 });
746 } 764 }
747 765
748 so.IsSelected = false; // fudge.... 766 // Fudge below is an extremely unhelpful comment. It's probably here so that the scheduled full update
767 // will succeed, as that will not update if an attachment is selected.
768 so.IsSelected = false; // fudge....
769
749 so.ScheduleGroupForFullUpdate(); 770 so.ScheduleGroupForFullUpdate();
750 } 771 }
751 772
@@ -782,8 +803,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
782 return newItem; 803 return newItem;
783 } 804 }
784 805
785 private string GetObjectScriptStates(SceneObjectGroup grp) 806 /// <summary>
807 /// Prepares the script instance for save.
808 /// </summary>
809 /// <remarks>
810 /// This involves triggering the detach event and getting the script state (which also stops the script)
811 /// This MUST be done outside sp.AttachmentsSyncLock, since otherwise there is a chance of deadlock if a
812 /// running script is performing attachment operations.
813 /// </remarks>
814 /// <returns>
815 /// The script state ready for persistence.
816 /// </returns>
817 /// <param name='grp'>
818 /// </param>
819 /// <param name='fireDetachEvent'>
820 /// If true, then fire the script event before we save its state.
821 /// </param>
822 private string PrepareScriptInstanceForSave(SceneObjectGroup grp, bool fireDetachEvent)
786 { 823 {
824 if (fireDetachEvent)
825 m_scene.EventManager.TriggerOnAttach(grp.LocalId, grp.FromItemID, UUID.Zero);
826
787 using (StringWriter sw = new StringWriter()) 827 using (StringWriter sw = new StringWriter())
788 { 828 {
789 using (XmlTextWriter writer = new XmlTextWriter(sw)) 829 using (XmlTextWriter writer = new XmlTextWriter(sw))
@@ -795,7 +835,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
795 } 835 }
796 } 836 }
797 837
798 private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so) 838 private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so, string scriptedState)
799 { 839 {
800 // Don't save attachments for HG visitors, it 840 // Don't save attachments for HG visitors, it
801 // messes up their inventory. When a HG visitor logs 841 // messes up their inventory. When a HG visitor logs
@@ -808,11 +848,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
808 && (m_scene.UserManagementModule == null 848 && (m_scene.UserManagementModule == null
809 || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID)); 849 || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
810 850
811 // Scripts MUST be snapshotted before the object is
812 // removed from the scene because doing otherwise will
813 // clobber the run flag
814 string scriptedState = GetObjectScriptStates(so);
815
816 // Remove the object from the scene so no more updates 851 // Remove the object from the scene so no more updates
817 // are sent. Doing this before the below changes will ensure 852 // are sent. Doing this before the below changes will ensure
818 // updates can't cause "HUD artefacts" 853 // updates can't cause "HUD artefacts"
@@ -836,97 +871,70 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
836 so.RemoveScriptInstances(true); 871 so.RemoveScriptInstances(true);
837 } 872 }
838 873
839 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so)
840 {
841 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
842
843 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
844 sp.RemoveAttachment(so);
845
846 UpdateDetachedObject(sp, so);
847 }
848
849 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 874 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
850 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc, bool append) 875 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc, bool append)
851 { 876 {
852 if (m_invAccessModule == null) 877 if (m_invAccessModule == null)
853 return null; 878 return null;
854 879
855 lock (sp.AttachmentsSyncLock) 880 SceneObjectGroup objatt;
856 {
857 SceneObjectGroup objatt;
858
859 if (itemID != UUID.Zero)
860 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
861 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
862 false, false, sp.UUID, true);
863 else
864 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
865 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
866 false, false, sp.UUID, true);
867
868 if (objatt != null)
869 {
870// m_log.DebugFormat(
871// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}",
872// objatt.Name, sp.Name, attachmentPt, m_scene.Name);
873
874 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
875 objatt.HasGroupChanged = false;
876 bool tainted = false;
877 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
878 tainted = true;
879
880 // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal
881 // course of events. If not, then it's probably not worth trying to recover the situation
882 // since this is more likely to trigger further exceptions and confuse later debugging. If
883 // exceptions can be thrown in expected error conditions (not NREs) then make this consistent
884 // since other normal error conditions will simply return false instead.
885 // This will throw if the attachment fails
886 try
887 {
888 AttachObjectInternal(sp, objatt, attachmentPt, false, false, false, append);
889 }
890 catch (Exception e)
891 {
892 m_log.ErrorFormat(
893 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
894 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
895
896 // Make sure the object doesn't stick around and bail
897 sp.RemoveAttachment(objatt);
898 m_scene.DeleteSceneObject(objatt, false);
899 return null;
900 }
901
902 if (tainted)
903 objatt.HasGroupChanged = true;
904 881
905 if (doc != null) 882 if (itemID != UUID.Zero)
906 { 883 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
907 objatt.LoadScriptState(doc); 884 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
908 objatt.ResetOwnerChangeFlag(); 885 false, false, sp.UUID, true);
909 } 886 else
887 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
888 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
889 false, false, sp.UUID, true);
910 890
911 // Fire after attach, so we don't get messy perms dialogs 891 if (objatt == null)
912 // 4 == AttachedRez 892 {
913 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); 893 m_log.WarnFormat(
914 objatt.ResumeScripts(); 894 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
895 itemID, sp.Name, attachmentPt);
915 896
916 // Do this last so that event listeners have access to all the effects of the attachment 897 return null;
917 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); 898 }
918 899
919 return objatt; 900 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
920 } 901 objatt.HasGroupChanged = false;
921 else 902 bool tainted = false;
903 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
904 tainted = true;
905
906 // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal
907 // course of events. If not, then it's probably not worth trying to recover the situation
908 // since this is more likely to trigger further exceptions and confuse later debugging. If
909 // exceptions can be thrown in expected error conditions (not NREs) then make this consistent
910 // since other normal error conditions will simply return false instead.
911 // This will throw if the attachment fails
912 try
913 {
914 if (doc != null)
922 { 915 {
923 m_log.WarnFormat( 916 objatt.LoadScriptState(doc);
924 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", 917 objatt.ResetOwnerChangeFlag();
925 itemID, sp.Name, attachmentPt);
926 } 918 }
919
920 AttachObjectInternal(sp, objatt, attachmentPt, false, true, false, true, append);
927 } 921 }
928 922 catch (Exception e)
929 return null; 923 {
924 m_log.ErrorFormat(
925 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
926 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
927
928 // Make sure the object doesn't stick around and bail
929 sp.RemoveAttachment(objatt);
930 m_scene.DeleteSceneObject(objatt, false);
931 return null;
932 }
933
934 if (tainted)
935 objatt.HasGroupChanged = true;
936
937 return objatt;
930 } 938 }
931 939
932 /// <summary> 940 /// <summary>
@@ -1084,17 +1092,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1084 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); 1092 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
1085 if (sp != null) 1093 if (sp != null)
1086 { 1094 {
1087 lock (sp.AttachmentsSyncLock) 1095 List<SceneObjectGroup> attachments = sp.GetAttachments();
1096
1097 foreach (SceneObjectGroup group in attachments)
1088 { 1098 {
1089 List<SceneObjectGroup> attachments = sp.GetAttachments(); 1099 if (group.FromItemID == itemID && group.FromItemID != UUID.Zero)
1090
1091 foreach (SceneObjectGroup group in attachments)
1092 { 1100 {
1093 if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) 1101 DetachSingleAttachmentToInv(sp, group);
1094 { 1102 return;
1095 DetachSingleAttachmentToInv(sp, group);
1096 return;
1097 }
1098 } 1103 }
1099 } 1104 }
1100 } 1105 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 545aeda..a8fe045 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -228,6 +228,120 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
228 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); 228 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
229 } 229 }
230 230
231 [Test]
232 public void TestWearAttachmentFromGround()
233 {
234 TestHelpers.InMethod();
235// TestHelpers.EnableLogging();
236
237 Scene scene = CreateTestScene();
238 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
239 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
240
241 SceneObjectGroup so2 = SceneHelpers.AddSceneObject(scene, "att2", sp.UUID);
242
243 {
244 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID);
245
246 m_numberOfAttachEventsFired = 0;
247 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false, false, false);
248
249 // Check status on scene presence
250 Assert.That(sp.HasAttachments(), Is.True);
251 List<SceneObjectGroup> attachments = sp.GetAttachments();
252 Assert.That(attachments.Count, Is.EqualTo(1));
253 SceneObjectGroup attSo = attachments[0];
254 Assert.That(attSo.Name, Is.EqualTo(so.Name));
255 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
256 Assert.That(attSo.IsAttachment);
257 Assert.That(attSo.UsesPhysics, Is.False);
258 Assert.That(attSo.IsTemporary, Is.False);
259
260 // Check item status
261 Assert.That(
262 sp.Appearance.GetAttachpoint(attSo.FromItemID),
263 Is.EqualTo((int)AttachmentPoint.LeftHand));
264
265 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
266 Assert.That(attachmentItem, Is.Not.Null);
267 Assert.That(attachmentItem.Name, Is.EqualTo(so.Name));
268
269 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
270 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
271
272 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2));
273
274 // Check events
275 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
276 }
277
278 // Test wearing a different attachment from the ground.
279 {
280 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false, false);
281
282 // Check status on scene presence
283 Assert.That(sp.HasAttachments(), Is.True);
284 List<SceneObjectGroup> attachments = sp.GetAttachments();
285 Assert.That(attachments.Count, Is.EqualTo(1));
286 SceneObjectGroup attSo = attachments[0];
287 Assert.That(attSo.Name, Is.EqualTo(so2.Name));
288 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
289 Assert.That(attSo.IsAttachment);
290 Assert.That(attSo.UsesPhysics, Is.False);
291 Assert.That(attSo.IsTemporary, Is.False);
292
293 // Check item status
294 Assert.That(
295 sp.Appearance.GetAttachpoint(attSo.FromItemID),
296 Is.EqualTo((int)AttachmentPoint.LeftHand));
297
298 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
299 Assert.That(attachmentItem, Is.Not.Null);
300 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
301
302 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
303 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
304
305 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
306
307 // Check events
308 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
309 }
310
311 // Test rewearing an already worn attachment from ground. Nothing should happen.
312 {
313 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false, false);
314
315 // Check status on scene presence
316 Assert.That(sp.HasAttachments(), Is.True);
317 List<SceneObjectGroup> attachments = sp.GetAttachments();
318 Assert.That(attachments.Count, Is.EqualTo(1));
319 SceneObjectGroup attSo = attachments[0];
320 Assert.That(attSo.Name, Is.EqualTo(so2.Name));
321 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
322 Assert.That(attSo.IsAttachment);
323 Assert.That(attSo.UsesPhysics, Is.False);
324 Assert.That(attSo.IsTemporary, Is.False);
325
326 // Check item status
327 Assert.That(
328 sp.Appearance.GetAttachpoint(attSo.FromItemID),
329 Is.EqualTo((int)AttachmentPoint.LeftHand));
330
331 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
332 Assert.That(attachmentItem, Is.Not.Null);
333 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
334
335 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
336 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
337
338 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
339
340 // Check events
341 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
342 }
343 }
344
231 /// <summary> 345 /// <summary>
232 /// Test that we do not attempt to attach an in-world object that someone else is sitting on. 346 /// Test that we do not attempt to attach an in-world object that someone else is sitting on.
233 /// </summary> 347 /// </summary>
@@ -275,29 +389,140 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
275 389
276 InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); 390 InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
277 391
278 m_numberOfAttachEventsFired = 0; 392 {
279 scene.AttachmentsModule.RezSingleAttachmentFromInventory( 393 scene.AttachmentsModule.RezSingleAttachmentFromInventory(
280 sp, attItem.ID, (uint)AttachmentPoint.Chest); 394 sp, attItem.ID, (uint)AttachmentPoint.Chest);
281 395
282 // Check scene presence status 396 // Check scene presence status
283 Assert.That(sp.HasAttachments(), Is.True); 397 Assert.That(sp.HasAttachments(), Is.True);
284 List<SceneObjectGroup> attachments = sp.GetAttachments(); 398 List<SceneObjectGroup> attachments = sp.GetAttachments();
285 Assert.That(attachments.Count, Is.EqualTo(1)); 399 Assert.That(attachments.Count, Is.EqualTo(1));
286 SceneObjectGroup attSo = attachments[0]; 400 SceneObjectGroup attSo = attachments[0];
287 Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); 401 Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
288 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); 402 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
289 Assert.That(attSo.IsAttachment); 403 Assert.That(attSo.IsAttachment);
290 Assert.That(attSo.UsesPhysics, Is.False); 404 Assert.That(attSo.UsesPhysics, Is.False);
291 Assert.That(attSo.IsTemporary, Is.False); 405 Assert.That(attSo.IsTemporary, Is.False);
406
407 // Check appearance status
408 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
409 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
410 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
411
412 // Check events
413 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
414 }
415
416 // Test attaching an already attached attachment
417 {
418 scene.AttachmentsModule.RezSingleAttachmentFromInventory(
419 sp, attItem.ID, (uint)AttachmentPoint.Chest);
292 420
293 // Check appearance status 421 // Check scene presence status
294 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); 422 Assert.That(sp.HasAttachments(), Is.True);
295 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); 423 List<SceneObjectGroup> attachments = sp.GetAttachments();
424 Assert.That(attachments.Count, Is.EqualTo(1));
425 SceneObjectGroup attSo = attachments[0];
426 Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
427 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
428 Assert.That(attSo.IsAttachment);
429 Assert.That(attSo.UsesPhysics, Is.False);
430 Assert.That(attSo.IsTemporary, Is.False);
431
432 // Check appearance status
433 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
434 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
435 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
436
437 // Check events
438 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
439 }
440 }
296 441
297 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 442 /// <summary>
443 /// Test wearing an attachment from inventory, as opposed to explicit choosing the rez point
444 /// </summary>
445 [Test]
446 public void TestWearAttachmentFromInventory()
447 {
448 TestHelpers.InMethod();
449// TestHelpers.EnableLogging();
298 450
299 // Check events 451 Scene scene = CreateTestScene();
300 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); 452 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
453 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
454
455 InventoryItemBase attItem1 = CreateAttachmentItem(scene, ua1.PrincipalID, "att1", 0x10, 0x20);
456 InventoryItemBase attItem2 = CreateAttachmentItem(scene, ua1.PrincipalID, "att2", 0x11, 0x21);
457
458 {
459 m_numberOfAttachEventsFired = 0;
460 scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem1.ID, (uint)AttachmentPoint.Default);
461
462 // default attachment point is currently the left hand.
463 Assert.That(sp.HasAttachments(), Is.True);
464 List<SceneObjectGroup> attachments = sp.GetAttachments();
465 Assert.That(attachments.Count, Is.EqualTo(1));
466 SceneObjectGroup attSo = attachments[0];
467 Assert.That(attSo.Name, Is.EqualTo(attItem1.Name));
468 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
469 Assert.That(attSo.IsAttachment);
470
471 // Check appearance status
472 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
473 Assert.That(sp.Appearance.GetAttachpoint(attItem1.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
474 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
475
476 // Check events
477 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
478 }
479
480 // Test wearing a second attachment at the same position
481 // Until multiple attachments at one point is implemented, this will remove the first attachment
482 // This test relies on both attachments having the same default attachment point (in this case LeftHand
483 // since none other has been set).
484 {
485 scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default);
486
487 // default attachment point is currently the left hand.
488 Assert.That(sp.HasAttachments(), Is.True);
489 List<SceneObjectGroup> attachments = sp.GetAttachments();
490 Assert.That(attachments.Count, Is.EqualTo(1));
491 SceneObjectGroup attSo = attachments[0];
492 Assert.That(attSo.Name, Is.EqualTo(attItem2.Name));
493 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
494 Assert.That(attSo.IsAttachment);
495
496 // Check appearance status
497 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
498 Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
499 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
500
501 // Check events
502 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
503 }
504
505 // Test wearing an already attached attachment
506 {
507 scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default);
508
509 // default attachment point is currently the left hand.
510 Assert.That(sp.HasAttachments(), Is.True);
511 List<SceneObjectGroup> attachments = sp.GetAttachments();
512 Assert.That(attachments.Count, Is.EqualTo(1));
513 SceneObjectGroup attSo = attachments[0];
514 Assert.That(attSo.Name, Is.EqualTo(attItem2.Name));
515 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
516 Assert.That(attSo.IsAttachment);
517
518 // Check appearance status
519 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
520 Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
521 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
522
523 // Check events
524 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
525 }
301 } 526 }
302 527
303 /// <summary> 528 /// <summary>
@@ -604,7 +829,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
604 sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); 829 sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
605 830
606 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); 831 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
607 ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager); 832
833 AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
834 TestClient tc = new TestClient(acd, sceneA, sh.SceneManager);
835 List<TestClient> destinationTestClients = new List<TestClient>();
836 EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients);
837
838 ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager);
608 beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); 839 beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
609 840
610 InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); 841 InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20);
@@ -623,7 +854,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
623 teleportLookAt, 854 teleportLookAt,
624 (uint)TeleportFlags.ViaLocation); 855 (uint)TeleportFlags.ViaLocation);
625 856
626 ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide(); 857 destinationTestClients[0].CompleteMovement();
627 858
628 // Check attachments have made it into sceneB 859 // Check attachments have made it into sceneB
629 ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); 860 ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID);
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 1adff7e..51fe1ea 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -322,6 +322,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
322 322
323 if (asset != null) 323 if (asset != null)
324 { 324 {
325 // Replace an HG ID with the simple asset ID so that we can persist textures for foreign HG avatars
326 asset.ID = asset.FullID.ToString();
327
325 asset.Temporary = false; 328 asset.Temporary = false;
326 asset.Local = false; 329 asset.Local = false;
327 m_scene.AssetService.Store(asset); 330 m_scene.AssetService.Store(asset);
@@ -358,7 +361,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
358 361
359 public void QueueAppearanceSave(UUID agentid) 362 public void QueueAppearanceSave(UUID agentid)
360 { 363 {
361 // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); 364// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
362 365
363 // 10000 ticks per millisecond, 1000 milliseconds per second 366 // 10000 ticks per millisecond, 1000 milliseconds per second
364 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); 367 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
@@ -655,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
655 return; 658 return;
656 } 659 }
657 660
658 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); 661// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
659 662
660 // This could take awhile since it needs to pull inventory 663 // This could take awhile since it needs to pull inventory
661 // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape 664 // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
@@ -664,6 +667,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
664 // multiple save requests. 667 // multiple save requests.
665 SetAppearanceAssets(sp.UUID, sp.Appearance); 668 SetAppearanceAssets(sp.UUID, sp.Appearance);
666 669
670// List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
671// foreach (AvatarAttachment att in attachments)
672// {
673// m_log.DebugFormat(
674// "[AVFACTORY]: For {0} saving attachment {1} at point {2}",
675// sp.Name, att.ItemID, att.AttachPoint);
676// }
677
667 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); 678 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
668 679
669 // Trigger this here because it's the final step in the set/queue/save process for appearance setting. 680 // Trigger this here because it's the final step in the set/queue/save process for appearance setting.
@@ -1087,7 +1098,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
1087 } 1098 }
1088 1099
1089 bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp); 1100 bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp);
1090 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); 1101 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete");
1091 } 1102 }
1092 } 1103 }
1093} 1104}
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
index e21547c..f090e15 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -39,7 +39,7 @@ using OpenSim.Tests.Common.Mock;
39namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory 39namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
40{ 40{
41 [TestFixture] 41 [TestFixture]
42 public class AvatarFactoryModuleTests 42 public class AvatarFactoryModuleTests : OpenSimTestCase
43 { 43 {
44 /// <summary> 44 /// <summary>
45 /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service. 45 /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service.
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 4c3f1cc..174642d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -256,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
256 // If camera is moved into client, then camera position can be used 256 // If camera is moved into client, then camera position can be used
257 // MT: No, it can't, as chat is heard from the avatar position, not 257 // MT: No, it can't, as chat is heard from the avatar position, not
258 // the camera position. 258 // the camera position.
259 s.ForEachRootScenePresence( 259 s.ForEachScenePresence(
260 delegate(ScenePresence presence) 260 delegate(ScenePresence presence)
261 { 261 {
262 if (destination != UUID.Zero && presence.UUID != destination) 262 if (destination != UUID.Zero && presence.UUID != destination)
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
index 7a197f7..961117e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
@@ -40,7 +40,7 @@ using OpenSim.Tests.Common.Mock;
40namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests 40namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
41{ 41{
42 [TestFixture] 42 [TestFixture]
43 public class FriendsModuleTests 43 public class FriendsModuleTests : OpenSimTestCase
44 { 44 {
45 private FriendsModule m_fm; 45 private FriendsModule m_fm;
46 private TestScene m_scene; 46 private TestScene m_scene;
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index cc266df..1627f6c 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
153 if (sp != null && !sp.IsChildAgent) 153 if (sp != null && !sp.IsChildAgent)
154 { 154 {
155 // Local message 155 // Local message
156 m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID); 156// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID);
157 157
158 sp.ControllingClient.SendInstantMessage(im); 158 sp.ControllingClient.SendInstantMessage(im);
159 159
@@ -166,14 +166,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
166 // try child avatar second 166 // try child avatar second
167 foreach (Scene scene in m_Scenes) 167 foreach (Scene scene in m_Scenes)
168 { 168 {
169 //m_log.DebugFormat( 169// m_log.DebugFormat(
170 // "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); 170// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
171 171
172 ScenePresence sp = scene.GetScenePresence(toAgentID); 172 ScenePresence sp = scene.GetScenePresence(toAgentID);
173 if (sp != null) 173 if (sp != null)
174 { 174 {
175 // Local message 175 // Local message
176 m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID); 176// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID);
177 177
178 sp.ControllingClient.SendInstantMessage(im); 178 sp.ControllingClient.SendInstantMessage(im);
179 179
@@ -183,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
183 } 183 }
184 } 184 }
185 185
186 m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); 186// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
187 187
188 SendGridInstantMessageViaXMLRPC(im, result); 188 SendGridInstantMessageViaXMLRPC(im, result);
189 } 189 }
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 3a44cc5..2d46276 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -189,20 +189,24 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
189 { 189 {
190 foreach (GridInstantMessage im in msglist) 190 foreach (GridInstantMessage im in msglist)
191 { 191 {
192 // client.SendInstantMessage(im); 192 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
193 193 // send it directly or else the item will be given twice
194 // Send through scene event manager so all modules get a chance 194 client.SendInstantMessage(im);
195 // to look at this message before it gets delivered. 195 else
196 // 196 {
197 // Needed for proper state management for stored group 197 // Send through scene event manager so all modules get a chance
198 // invitations 198 // to look at this message before it gets delivered.
199 // 199 //
200 200 // Needed for proper state management for stored group
201 im.offline = 1; 201 // invitations
202 202 //
203 Scene s = FindScene(client.AgentId); 203
204 if (s != null) 204 im.offline = 1;
205 s.EventManager.TriggerIncomingInstantMessage(im); 205
206 Scene s = FindScene(client.AgentId);
207 if (s != null)
208 s.EventManager.TriggerIncomingInstantMessage(im);
209 }
206 } 210 }
207 } 211 }
208 } 212 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index dc2b0e0..659b178 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -161,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
161 string filePath = "ERROR"; 161 string filePath = "ERROR";
162 162
163 List<InventoryFolderBase> folderCandidates 163 List<InventoryFolderBase> folderCandidates
164 = InventoryArchiveUtils.FindFolderByPath( 164 = InventoryArchiveUtils.FindFoldersByPath(
165 m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); 165 m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath);
166 166
167 if (folderCandidates.Count == 0) 167 if (folderCandidates.Count == 0)
@@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
296 // iar name and try to find that instead. 296 // iar name and try to find that instead.
297 string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); 297 string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath);
298 List<InventoryFolderBase> folderCandidates 298 List<InventoryFolderBase> folderCandidates
299 = InventoryArchiveUtils.FindFolderByPath( 299 = InventoryArchiveUtils.FindFoldersByPath(
300 m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); 300 m_scene.InventoryService, m_userInfo.PrincipalID, plainPath);
301 301
302 if (folderCandidates.Count != 0) 302 if (folderCandidates.Count != 0)
@@ -487,6 +487,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
487 { 487 {
488// m_log.DebugFormat( 488// m_log.DebugFormat(
489// "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count); 489// "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count);
490
491 if (coa.Objects.Count == 0)
492 {
493 m_log.WarnFormat(
494 "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of coalesced object from asset {0} as it has zero loaded components",
495 assetId);
496 return false;
497 }
490 498
491 sceneObjects.AddRange(coa.Objects); 499 sceneObjects.AddRange(coa.Objects);
492 } 500 }
@@ -495,7 +503,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
495 SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 503 SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
496 504
497 if (deserializedObject != null) 505 if (deserializedObject != null)
506 {
498 sceneObjects.Add(deserializedObject); 507 sceneObjects.Add(deserializedObject);
508 }
509 else
510 {
511 m_log.WarnFormat(
512 "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of object from asset {0} as deserialization failed",
513 assetId);
514
515 return false;
516 }
499 } 517 }
500 518
501 foreach (SceneObjectGroup sog in sceneObjects) 519 foreach (SceneObjectGroup sog in sceneObjects)
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index 0d90a15..dbaf2aa 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -52,13 +52,82 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
52 /// <summary> 52 /// <summary>
53 /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder 53 /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder
54 /// </summary> 54 /// </summary>
55 /// <remarks>
56 /// This method does not handle paths that contain multiple delimitors
57 ///
58 /// FIXME: We have no way of distinguishing folders with the same path
55 /// 59 ///
60 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
61 /// </remarks>
62 /// <param name="inventoryService">
63 /// Inventory service to query
64 /// </param>
65 /// <param name="userId">
66 /// User id to search
67 /// </param>
68 /// <param name="path">
69 /// The path to the required folder.
70 /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
71 /// </param>
72 /// <returns>The folder found. Please note that if there are multiple folders with the same name then an
73 /// unspecified one will be returned. If no such folder eixsts then null is returned</returns>
74 public static InventoryFolderBase FindFolderByPath(
75 IInventoryService inventoryService, UUID userId, string path)
76 {
77 List<InventoryFolderBase> folders = FindFoldersByPath(inventoryService, userId, path);
78
79 if (folders.Count == 0)
80 return null;
81 else
82 return folders[0];
83 }
84
85 /// <summary>
86 /// Find a folder given a PATH_DELIMITER delimited path starting from a given folder
87 /// </summary>
88 /// <remarks>
56 /// This method does not handle paths that contain multiple delimitors 89 /// This method does not handle paths that contain multiple delimitors
57 /// 90 ///
58 /// FIXME: We have no way of distinguishing folders with the same path 91 /// FIXME: We have no way of distinguishing folders with the same path
59 /// 92 ///
60 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 93 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
94 /// </remarks>
95 /// <param name="inventoryService">
96 /// Inventory service to query
97 /// </param>
98 /// <param name="startFolder">
99 /// The folder from which the path starts
100 /// </param>
101 /// <param name="path">
102 /// The path to the required folder.
103 /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
104 /// </param>
105 /// <returns>The folder found. Please note that if there are multiple folders with the same name then an
106 /// unspecified one will be returned. If no such folder eixsts then null is returned</returns>
107 public static InventoryFolderBase FindFolderByPath(
108 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
109 {
110 if (null == startFolder)
111 return null;
112
113 List<InventoryFolderBase> folders = FindFoldersByPath(inventoryService, startFolder, path);
114
115 if (folders.Count == 0)
116 return null;
117 else
118 return folders[0];
119 }
120
121 /// <summary>
122 /// Find a set of folders given a PATH_DELIMITER delimited path starting from a user's root folder
123 /// </summary>
124 /// <remarks>
125 /// This method does not handle paths that contain multiple delimitors
126 ///
127 /// FIXME: We have no way of distinguishing folders with the same path
61 /// 128 ///
129 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
130 /// </remarks>
62 /// <param name="inventoryService"> 131 /// <param name="inventoryService">
63 /// Inventory service to query 132 /// Inventory service to query
64 /// </param> 133 /// </param>
@@ -70,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
70 /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. 139 /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
71 /// </param> 140 /// </param>
72 /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns> 141 /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns>
73 public static List<InventoryFolderBase> FindFolderByPath( 142 public static List<InventoryFolderBase> FindFoldersByPath(
74 IInventoryService inventoryService, UUID userId, string path) 143 IInventoryService inventoryService, UUID userId, string path)
75 { 144 {
76 InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId); 145 InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
@@ -78,19 +147,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
78 if (null == rootFolder) 147 if (null == rootFolder)
79 return new List<InventoryFolderBase>(); 148 return new List<InventoryFolderBase>();
80 149
81 return FindFolderByPath(inventoryService, rootFolder, path); 150 return FindFoldersByPath(inventoryService, rootFolder, path);
82 } 151 }
83 152
84 /// <summary> 153 /// <summary>
85 /// Find a folder given a PATH_DELIMITER delimited path starting from this folder 154 /// Find a set of folders given a PATH_DELIMITER delimited path starting from this folder
86 /// </summary> 155 /// </summary>
87 /// 156 /// <remarks>
88 /// This method does not handle paths that contain multiple delimitors 157 /// This method does not handle paths that contain multiple delimitors
89 /// 158 ///
90 /// FIXME: We have no way of distinguishing folders with the same path. 159 /// FIXME: We have no way of distinguishing folders with the same path.
91 /// 160 ///
92 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 161 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
93 /// 162 /// </remarks>
94 /// <param name="inventoryService"> 163 /// <param name="inventoryService">
95 /// Inventory service to query 164 /// Inventory service to query
96 /// </param> 165 /// </param>
@@ -102,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
102 /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. 171 /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
103 /// </param> 172 /// </param>
104 /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns> 173 /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns>
105 public static List<InventoryFolderBase> FindFolderByPath( 174 public static List<InventoryFolderBase> FindFoldersByPath(
106 IInventoryService inventoryService, InventoryFolderBase startFolder, string path) 175 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
107 { 176 {
108 List<InventoryFolderBase> foundFolders = new List<InventoryFolderBase>(); 177 List<InventoryFolderBase> foundFolders = new List<InventoryFolderBase>();
@@ -133,12 +202,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
133 202
134 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 203 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
135 204
205// m_log.DebugFormat(
206// "Found {0} folders in {1} for {2}", contents.Folders.Count, startFolder.Name, startFolder.Owner);
207
136 foreach (InventoryFolderBase folder in contents.Folders) 208 foreach (InventoryFolderBase folder in contents.Folders)
137 { 209 {
138 if (folder.Name == components[0]) 210 if (folder.Name == components[0])
139 { 211 {
140 if (components.Length > 1) 212 if (components.Length > 1)
141 foundFolders.AddRange(FindFolderByPath(inventoryService, folder, components[1])); 213 foundFolders.AddRange(FindFoldersByPath(inventoryService, folder, components[1]));
142 else 214 else
143 foundFolders.Add(folder); 215 foundFolders.Add(folder);
144 } 216 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index d0e88f6..4ec8ae7 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
124 SaveAssets = true; 124 SaveAssets = true;
125 } 125 }
126 126
127 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) 127 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut)
128 { 128 {
129 Exception reportedException = null; 129 Exception reportedException = null;
130 bool succeeded = true; 130 bool succeeded = true;
@@ -143,6 +143,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
143 m_saveStream.Close(); 143 m_saveStream.Close();
144 } 144 }
145 145
146 if (timedOut)
147 {
148 succeeded = false;
149 reportedException = new Exception("Loading assets timed out");
150 }
151
146 m_module.TriggerInventoryArchiveSaved( 152 m_module.TriggerInventoryArchiveSaved(
147 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); 153 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException);
148 } 154 }
@@ -266,6 +272,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
266 saveFolderContentsOnly = true; 272 saveFolderContentsOnly = true;
267 maxComponentIndex--; 273 maxComponentIndex--;
268 } 274 }
275 else if (maxComponentIndex == -1)
276 {
277 // If the user has just specified "/", then don't save the root "My Inventory" folder. This is
278 // more intuitive then requiring the user to specify "/*" for this.
279 saveFolderContentsOnly = true;
280 }
269 281
270 m_invPath = String.Empty; 282 m_invPath = String.Empty;
271 for (int i = 0; i <= maxComponentIndex; i++) 283 for (int i = 0; i <= maxComponentIndex; i++)
@@ -283,7 +295,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
283 { 295 {
284 m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); 296 m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
285 List<InventoryFolderBase> candidateFolders 297 List<InventoryFolderBase> candidateFolders
286 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); 298 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, rootFolder, m_invPath);
287 if (candidateFolders.Count > 0) 299 if (candidateFolders.Count > 0)
288 inventoryFolder = candidateFolders[0]; 300 inventoryFolder = candidateFolders[0];
289 } 301 }
@@ -350,7 +362,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
350 { 362 {
351 m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified"); 363 m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified");
352 364
353 ReceivedAllAssets(new List<UUID>(), new List<UUID>()); 365 ReceivedAllAssets(new List<UUID>(), new List<UUID>(), false);
354 } 366 }
355 } 367 }
356 catch (Exception) 368 catch (Exception)
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs
index 6eb3605..95f562e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs
@@ -48,125 +48,9 @@ using OpenSim.Tests.Common.Mock;
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 49{
50 [TestFixture] 50 [TestFixture]
51 public class PathTests : InventoryArchiveTestCase 51 public class InventoryArchiveLoadPathTests : InventoryArchiveTestCase
52 { 52 {
53 /// <summary> 53 /// <summary>
54 /// Test saving an inventory path to a V0.1 OpenSim Inventory Archive
55 /// (subject to change since there is no fixed format yet).
56 /// </summary>
57 [Test]
58 public void TestSavePathToIarV0_1()
59 {
60 TestHelpers.InMethod();
61// log4net.Config.XmlConfigurator.Configure();
62
63 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
64
65 Scene scene = new SceneHelpers().SetupScene();
66 SceneHelpers.SetupSceneModules(scene, archiverModule);
67
68 // Create user
69 string userFirstName = "Jock";
70 string userLastName = "Stirrup";
71 string userPassword = "troll";
72 UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
73 UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword);
74
75 // Create asset
76 SceneObjectGroup object1;
77 SceneObjectPart part1;
78 {
79 string partName = "My Little Dog Object";
80 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
81 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
82 Vector3 groupPosition = new Vector3(10, 20, 30);
83 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
84 Vector3 offsetPosition = new Vector3(5, 10, 15);
85
86 part1 = new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition);
87 part1.Name = partName;
88
89 object1 = new SceneObjectGroup(part1);
90 scene.AddNewSceneObject(object1, false);
91 }
92
93 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
94 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
95 scene.AssetService.Store(asset1);
96
97 // Create item
98 UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
99 InventoryItemBase item1 = new InventoryItemBase();
100 item1.Name = "My Little Dog";
101 item1.AssetID = asset1.FullID;
102 item1.ID = item1Id;
103 InventoryFolderBase objsFolder
104 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0];
105 item1.Folder = objsFolder.ID;
106 scene.AddInventoryItem(item1);
107
108 MemoryStream archiveWriteStream = new MemoryStream();
109 archiverModule.OnInventoryArchiveSaved += SaveCompleted;
110
111 // Test saving a particular path
112 mre.Reset();
113 archiverModule.ArchiveInventory(
114 Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
115 mre.WaitOne(60000, false);
116
117 byte[] archive = archiveWriteStream.ToArray();
118 MemoryStream archiveReadStream = new MemoryStream(archive);
119 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
120
121 //bool gotControlFile = false;
122 bool gotObject1File = false;
123 //bool gotObject2File = false;
124 string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1);
125 string expectedObject1FilePath = string.Format(
126 "{0}{1}{2}",
127 ArchiveConstants.INVENTORY_PATH,
128 InventoryArchiveWriteRequest.CreateArchiveFolderName(objsFolder),
129 expectedObject1FileName);
130
131 string filePath;
132 TarArchiveReader.TarEntryType tarEntryType;
133
134// Console.WriteLine("Reading archive");
135
136 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
137 {
138// Console.WriteLine("Got {0}", filePath);
139
140// if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
141// {
142// gotControlFile = true;
143// }
144
145 if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml"))
146 {
147// string fileName = filePath.Remove(0, "Objects/".Length);
148//
149// if (fileName.StartsWith(part1.Name))
150// {
151 Assert.That(expectedObject1FilePath, Is.EqualTo(filePath));
152 gotObject1File = true;
153// }
154// else if (fileName.StartsWith(part2.Name))
155// {
156// Assert.That(fileName, Is.EqualTo(expectedObject2FileName));
157// gotObject2File = true;
158// }
159 }
160 }
161
162// Assert.That(gotControlFile, Is.True, "No control file in archive");
163 Assert.That(gotObject1File, Is.True, "No item1 file in archive");
164// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
165
166 // TODO: Test presence of more files and contents of files.
167 }
168
169 /// <summary>
170 /// Test loading an IAR to various different inventory paths. 54 /// Test loading an IAR to various different inventory paths.
171 /// </summary> 55 /// </summary>
172 [Test] 56 [Test]
@@ -193,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
193 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); 77 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
194 78
195 // Now try loading to a root child folder 79 // Now try loading to a root child folder
196 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA"); 80 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false);
197 MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); 81 MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray());
198 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); 82 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream);
199 83
@@ -202,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
202 Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); 86 Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");
203 87
204 // Now try loading to a more deeply nested folder 88 // Now try loading to a more deeply nested folder
205 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC"); 89 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false);
206 archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); 90 archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
207 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); 91 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream);
208 92
@@ -287,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
287 item1.AssetID = asset1.FullID; 171 item1.AssetID = asset1.FullID;
288 item1.ID = item1Id; 172 item1.ID = item1Id;
289 InventoryFolderBase objsFolder 173 InventoryFolderBase objsFolder
290 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0]; 174 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0];
291 item1.Folder = objsFolder.ID; 175 item1.Folder = objsFolder.ID;
292 scene.AddInventoryItem(item1); 176 scene.AddInventoryItem(item1);
293 177
@@ -351,12 +235,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
351 foldersCreated, nodesLoaded); 235 foldersCreated, nodesLoaded);
352 236
353 List<InventoryFolderBase> folder1Candidates 237 List<InventoryFolderBase> folder1Candidates
354 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); 238 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
355 Assert.That(folder1Candidates.Count, Is.EqualTo(1)); 239 Assert.That(folder1Candidates.Count, Is.EqualTo(1));
356 240
357 InventoryFolderBase folder1 = folder1Candidates[0]; 241 InventoryFolderBase folder1 = folder1Candidates[0];
358 List<InventoryFolderBase> folder2aCandidates 242 List<InventoryFolderBase> folder2aCandidates
359 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName); 243 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName);
360 Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); 244 Assert.That(folder2aCandidates.Count, Is.EqualTo(1));
361 } 245 }
362 246
@@ -368,17 +252,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
368 foldersCreated, nodesLoaded); 252 foldersCreated, nodesLoaded);
369 253
370 List<InventoryFolderBase> folder1Candidates 254 List<InventoryFolderBase> folder1Candidates
371 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); 255 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
372 Assert.That(folder1Candidates.Count, Is.EqualTo(1)); 256 Assert.That(folder1Candidates.Count, Is.EqualTo(1));
373 257
374 InventoryFolderBase folder1 = folder1Candidates[0]; 258 InventoryFolderBase folder1 = folder1Candidates[0];
375 259
376 List<InventoryFolderBase> folder2aCandidates 260 List<InventoryFolderBase> folder2aCandidates
377 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName); 261 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName);
378 Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); 262 Assert.That(folder2aCandidates.Count, Is.EqualTo(1));
379 263
380 List<InventoryFolderBase> folder2bCandidates 264 List<InventoryFolderBase> folder2bCandidates
381 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2bName); 265 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2bName);
382 Assert.That(folder2bCandidates.Count, Is.EqualTo(1)); 266 Assert.That(folder2bCandidates.Count, Is.EqualTo(1));
383 } 267 }
384 } 268 }
@@ -401,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
401 285
402 InventoryFolderBase folder1 286 InventoryFolderBase folder1
403 = UserInventoryHelpers.CreateInventoryFolder( 287 = UserInventoryHelpers.CreateInventoryFolder(
404 scene.InventoryService, ua1.PrincipalID, folder1ExistingName); 288 scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false);
405 289
406 string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); 290 string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
407 string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); 291 string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
@@ -414,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
414 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); 298 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
415 299
416 List<InventoryFolderBase> folder1PostCandidates 300 List<InventoryFolderBase> folder1PostCandidates
417 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); 301 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
418 Assert.That(folder1PostCandidates.Count, Is.EqualTo(2)); 302 Assert.That(folder1PostCandidates.Count, Is.EqualTo(2));
419 303
420 // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder. 304 // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder.
@@ -430,7 +314,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
430// Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID)); 314// Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID));
431 315
432 List<InventoryFolderBase> folder2PostCandidates 316 List<InventoryFolderBase> folder2PostCandidates
433 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b"); 317 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1Post, "b");
434 Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); 318 Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
435 } 319 }
436 320
@@ -452,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
452 336
453 InventoryFolderBase folder1 337 InventoryFolderBase folder1
454 = UserInventoryHelpers.CreateInventoryFolder( 338 = UserInventoryHelpers.CreateInventoryFolder(
455 scene.InventoryService, ua1.PrincipalID, folder1ExistingName); 339 scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false);
456 340
457 string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); 341 string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
458 string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); 342 string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
@@ -465,13 +349,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
465 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); 349 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
466 350
467 List<InventoryFolderBase> folder1PostCandidates 351 List<InventoryFolderBase> folder1PostCandidates
468 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); 352 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
469 Assert.That(folder1PostCandidates.Count, Is.EqualTo(1)); 353 Assert.That(folder1PostCandidates.Count, Is.EqualTo(1));
470 Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID)); 354 Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID));
471 355
472 List<InventoryFolderBase> folder2PostCandidates 356 List<InventoryFolderBase> folder2PostCandidates
473 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b"); 357 = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1PostCandidates[0], "b");
474 Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); 358 Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
475 } 359 }
476 } 360 }
477} \ No newline at end of file 361}
362
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs
new file mode 100644
index 0000000..1b521fc
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs
@@ -0,0 +1,194 @@
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.IO;
31using System.Reflection;
32using System.Threading;
33using NUnit.Framework;
34using OpenMetaverse;
35using OpenSim.Data;
36using OpenSim.Framework;
37using OpenSim.Framework.Serialization;
38using OpenSim.Framework.Serialization.External;
39using OpenSim.Framework.Communications;
40using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
41using OpenSim.Region.CoreModules.World.Serialiser;
42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{
50 [TestFixture]
51 public class InventoryArchiveLoadTests : InventoryArchiveTestCase
52 {
53 protected TestScene m_scene;
54 protected InventoryArchiverModule m_archiverModule;
55
56 [SetUp]
57 public override void SetUp()
58 {
59 base.SetUp();
60
61 SerialiserModule serialiserModule = new SerialiserModule();
62 m_archiverModule = new InventoryArchiverModule();
63
64 m_scene = new SceneHelpers().SetupScene();
65 SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
66 }
67
68 [Test]
69 public void TestLoadCoalesecedItem()
70 {
71 TestHelpers.InMethod();
72// TestHelpers.EnableLogging();
73
74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
75 m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
76
77 InventoryItemBase coaItem
78 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName);
79
80 Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1");
81
82 string assetXml = AssetHelpers.ReadAssetAsString(m_scene.AssetService, coaItem.AssetID);
83
84 CoalescedSceneObjects coa;
85 bool readResult = CoalescedSceneObjectsSerializer.TryFromXml(assetXml, out coa);
86
87 Assert.That(readResult, Is.True);
88 Assert.That(coa.Count, Is.EqualTo(2));
89
90 List<SceneObjectGroup> coaObjects = coa.Objects;
91 Assert.That(coaObjects[0].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000120")));
92 Assert.That(coaObjects[0].AbsolutePosition, Is.EqualTo(new Vector3(15, 30, 45)));
93
94 Assert.That(coaObjects[1].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000140")));
95 Assert.That(coaObjects[1].AbsolutePosition, Is.EqualTo(new Vector3(25, 50, 75)));
96 }
97
98 /// <summary>
99 /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized
100 /// objects.
101 /// </summary>
102 [Test]
103 public void TestLoadIarCreatorAccountPresent()
104 {
105 TestHelpers.InMethod();
106// log4net.Config.XmlConfigurator.Configure();
107
108 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
109
110 m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream);
111 InventoryItemBase foundItem1
112 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name);
113
114 Assert.That(
115 foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()),
116 "Loaded item non-uuid creator doesn't match original");
117 Assert.That(
118 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID),
119 "Loaded item uuid creator doesn't match original");
120 Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID),
121 "Loaded item owner doesn't match inventory reciever");
122
123 AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
124 string xmlData = Utils.BytesToString(asset1.Data);
125 SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
126
127 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
128 }
129
130// /// <summary>
131// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
132// /// an account exists with the same name as the creator, though not the same id.
133// /// </summary>
134// [Test]
135// public void TestLoadIarV0_1SameNameCreator()
136// {
137// TestHelpers.InMethod();
138// TestHelpers.EnableLogging();
139//
140// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
141// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
142//
143// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
144// InventoryItemBase foundItem1
145// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
146//
147// Assert.That(
148// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
149// "Loaded item non-uuid creator doesn't match original");
150// Assert.That(
151// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
152// "Loaded item uuid creator doesn't match original");
153// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
154// "Loaded item owner doesn't match inventory reciever");
155//
156// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
157// string xmlData = Utils.BytesToString(asset1.Data);
158// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
159//
160// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
161// }
162
163 /// <summary>
164 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
165 /// the creator or an account with the creator's name does not exist within the system.
166 /// </summary>
167 [Test]
168 public void TestLoadIarV0_1AbsentCreator()
169 {
170 TestHelpers.InMethod();
171// log4net.Config.XmlConfigurator.Configure();
172
173 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
174 m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream);
175
176 InventoryItemBase foundItem1
177 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
178
179 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
180 Assert.That(
181 foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()),
182 "Loaded item non-uuid creator doesn't match that of the loading user");
183 Assert.That(
184 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID),
185 "Loaded item uuid creator doesn't match that of the loading user");
186
187 AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
188 string xmlData = Utils.BytesToString(asset1.Data);
189 SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
190
191 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID));
192 }
193 }
194} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs
index 06f6e49..5e7e24c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs
@@ -48,7 +48,7 @@ using OpenSim.Tests.Common.Mock;
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 49{
50 [TestFixture] 50 [TestFixture]
51 public class InventoryArchiverTests : InventoryArchiveTestCase 51 public class InventoryArchiveSaveTests : InventoryArchiveTestCase
52 { 52 {
53 protected TestScene m_scene; 53 protected TestScene m_scene;
54 protected InventoryArchiverModule m_archiverModule; 54 protected InventoryArchiverModule m_archiverModule;
@@ -64,36 +64,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
64 m_scene = new SceneHelpers().SetupScene(); 64 m_scene = new SceneHelpers().SetupScene();
65 SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); 65 SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
66 } 66 }
67
68 [Test]
69 public void TestLoadCoalesecedItem()
70 {
71 TestHelpers.InMethod();
72// TestHelpers.EnableLogging();
73
74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
75 m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
76
77 InventoryItemBase coaItem
78 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName);
79
80 Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1");
81
82 string assetXml = AssetHelpers.ReadAssetAsString(m_scene.AssetService, coaItem.AssetID);
83
84 CoalescedSceneObjects coa;
85 bool readResult = CoalescedSceneObjectsSerializer.TryFromXml(assetXml, out coa);
86
87 Assert.That(readResult, Is.True);
88 Assert.That(coa.Count, Is.EqualTo(2));
89
90 List<SceneObjectGroup> coaObjects = coa.Objects;
91 Assert.That(coaObjects[0].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000120")));
92 Assert.That(coaObjects[0].AbsolutePosition, Is.EqualTo(new Vector3(15, 30, 45)));
93
94 Assert.That(coaObjects[1].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000140")));
95 Assert.That(coaObjects[1].AbsolutePosition, Is.EqualTo(new Vector3(25, 50, 75)));
96 }
97 67
98 /// <summary> 68 /// <summary>
99 /// Test that the IAR has the required files in the right order. 69 /// Test that the IAR has the required files in the right order.
@@ -121,6 +91,139 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
121 91
122 Assert.That(iarr.ControlFileLoaded, Is.True); 92 Assert.That(iarr.ControlFileLoaded, Is.True);
123 } 93 }
94
95 [Test]
96 public void TestSaveRootFolderToIar()
97 {
98 TestHelpers.InMethod();
99// TestHelpers.EnableLogging();
100
101 string userFirstName = "Jock";
102 string userLastName = "Stirrup";
103 string userPassword = "troll";
104 UUID userId = TestHelpers.ParseTail(0x20);
105
106 UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword);
107
108 MemoryStream archiveWriteStream = new MemoryStream();
109 m_archiverModule.OnInventoryArchiveSaved += SaveCompleted;
110
111 mre.Reset();
112 m_archiverModule.ArchiveInventory(
113 Guid.NewGuid(), userFirstName, userLastName, "/", userPassword, archiveWriteStream);
114 mre.WaitOne(60000, false);
115
116 // Test created iar
117 byte[] archive = archiveWriteStream.ToArray();
118 MemoryStream archiveReadStream = new MemoryStream(archive);
119 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
120
121// InventoryArchiveUtils.
122 bool gotObjectsFolder = false;
123
124 string objectsFolderName
125 = string.Format(
126 "{0}{1}",
127 ArchiveConstants.INVENTORY_PATH,
128 InventoryArchiveWriteRequest.CreateArchiveFolderName(
129 UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, userId, "Objects")));
130
131 string filePath;
132 TarArchiveReader.TarEntryType tarEntryType;
133
134 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
135 {
136// Console.WriteLine("Got {0}", filePath);
137
138 // Lazily, we only bother to look for the system objects folder created when we call CreateUserWithInventory()
139 // XXX: But really we need to stop all that stuff being created in tests or check for such folders
140 // more thoroughly
141 if (filePath == objectsFolderName)
142 gotObjectsFolder = true;
143 }
144
145 Assert.That(gotObjectsFolder, Is.True);
146 }
147
148 [Test]
149 public void TestSaveNonRootFolderToIar()
150 {
151 TestHelpers.InMethod();
152// TestHelpers.EnableLogging();
153
154 string userFirstName = "Jock";
155 string userLastName = "Stirrup";
156 string userPassword = "troll";
157 UUID userId = TestHelpers.ParseTail(0x20);
158
159 UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword);
160
161 // Create base folder
162 InventoryFolderBase f1
163 = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1", true);
164
165 // Create item1
166 SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Dog Object", 0x5);
167 InventoryItemBase i1 = UserInventoryHelpers.AddInventoryItem(m_scene, so1, 0x50, 0x60, "f1");
168
169 // Create embedded folder
170 InventoryFolderBase f1_1
171 = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1/f1.1", true);
172
173 // Create embedded item
174 SceneObjectGroup so1_1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Cat Object", 0x6);
175 InventoryItemBase i2 = UserInventoryHelpers.AddInventoryItem(m_scene, so1_1, 0x500, 0x600, "f1/f1.1");
176
177 MemoryStream archiveWriteStream = new MemoryStream();
178 m_archiverModule.OnInventoryArchiveSaved += SaveCompleted;
179
180 mre.Reset();
181 m_archiverModule.ArchiveInventory(
182 Guid.NewGuid(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream);
183 mre.WaitOne(60000, false);
184
185 // Test created iar
186 byte[] archive = archiveWriteStream.ToArray();
187 MemoryStream archiveReadStream = new MemoryStream(archive);
188 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
189
190// InventoryArchiveUtils.
191 bool gotf1 = false, gotf1_1 = false, gotso1 = false, gotso2 = false;
192
193 string f1FileName
194 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1));
195 string f1_1FileName
196 = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1_1));
197 string so1FileName
198 = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i1));
199 string so2FileName
200 = string.Format("{0}{1}", f1_1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i2));
201
202 string filePath;
203 TarArchiveReader.TarEntryType tarEntryType;
204
205 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
206 {
207// Console.WriteLine("Got {0}", filePath);
208
209 if (filePath == f1FileName)
210 gotf1 = true;
211 else if (filePath == f1_1FileName)
212 gotf1_1 = true;
213 else if (filePath == so1FileName)
214 gotso1 = true;
215 else if (filePath == so2FileName)
216 gotso2 = true;
217 }
218
219// Assert.That(gotControlFile, Is.True, "No control file in archive");
220 Assert.That(gotf1, Is.True);
221 Assert.That(gotf1_1, Is.True);
222 Assert.That(gotso1, Is.True);
223 Assert.That(gotso2, Is.True);
224
225 // TODO: Test presence of more files and contents of files.
226 }
124 227
125 /// <summary> 228 /// <summary>
126 /// Test saving a single inventory item to an IAR 229 /// Test saving a single inventory item to an IAR
@@ -155,7 +258,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
155 item1.AssetID = asset1.FullID; 258 item1.AssetID = asset1.FullID;
156 item1.ID = item1Id; 259 item1.ID = item1Id;
157 InventoryFolderBase objsFolder 260 InventoryFolderBase objsFolder
158 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; 261 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0];
159 item1.Folder = objsFolder.ID; 262 item1.Folder = objsFolder.ID;
160 m_scene.AddInventoryItem(item1); 263 m_scene.AddInventoryItem(item1);
161 264
@@ -250,7 +353,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
250 item1.AssetID = asset1.FullID; 353 item1.AssetID = asset1.FullID;
251 item1.ID = item1Id; 354 item1.ID = item1Id;
252 InventoryFolderBase objsFolder 355 InventoryFolderBase objsFolder
253 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; 356 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0];
254 item1.Folder = objsFolder.ID; 357 item1.Folder = objsFolder.ID;
255 m_scene.AddInventoryItem(item1); 358 m_scene.AddInventoryItem(item1);
256 359
@@ -317,101 +420,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
317 420
318 // TODO: Test presence of more files and contents of files. 421 // TODO: Test presence of more files and contents of files.
319 } 422 }
320
321 /// <summary>
322 /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized
323 /// objects.
324 /// </summary>
325 [Test]
326 public void TestLoadIarCreatorAccountPresent()
327 {
328 TestHelpers.InMethod();
329// log4net.Config.XmlConfigurator.Configure();
330
331 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
332
333 m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream);
334 InventoryItemBase foundItem1
335 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name);
336
337 Assert.That(
338 foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()),
339 "Loaded item non-uuid creator doesn't match original");
340 Assert.That(
341 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID),
342 "Loaded item uuid creator doesn't match original");
343 Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID),
344 "Loaded item owner doesn't match inventory reciever");
345
346 AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
347 string xmlData = Utils.BytesToString(asset1.Data);
348 SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
349
350 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
351 }
352
353// /// <summary>
354// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
355// /// an account exists with the same name as the creator, though not the same id.
356// /// </summary>
357// [Test]
358// public void TestLoadIarV0_1SameNameCreator()
359// {
360// TestHelpers.InMethod();
361// TestHelpers.EnableLogging();
362//
363// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
364// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
365//
366// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
367// InventoryItemBase foundItem1
368// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
369//
370// Assert.That(
371// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
372// "Loaded item non-uuid creator doesn't match original");
373// Assert.That(
374// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
375// "Loaded item uuid creator doesn't match original");
376// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
377// "Loaded item owner doesn't match inventory reciever");
378//
379// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
380// string xmlData = Utils.BytesToString(asset1.Data);
381// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
382//
383// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
384// }
385
386 /// <summary>
387 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
388 /// the creator or an account with the creator's name does not exist within the system.
389 /// </summary>
390 [Test]
391 public void TestLoadIarV0_1AbsentCreator()
392 {
393 TestHelpers.InMethod();
394// log4net.Config.XmlConfigurator.Configure();
395
396 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
397 m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream);
398
399 InventoryItemBase foundItem1
400 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
401
402 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
403 Assert.That(
404 foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()),
405 "Loaded item non-uuid creator doesn't match that of the loading user");
406 Assert.That(
407 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID),
408 "Loaded item uuid creator doesn't match that of the loading user");
409
410 AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
411 string xmlData = Utils.BytesToString(asset1.Data);
412 SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
413
414 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID));
415 }
416 } 423 }
417} \ No newline at end of file 424} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 4cfa33d..ae58dfd 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -316,76 +316,74 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
316 } 316 }
317 } 317 }
318 318
319 // Disabled for now as it looks like http://opensimulator.org/mantis/view.php?id=6311 was fixed by fixes 319 // XXX: This code was placed here to try and accomodate RLV which moves given folders named #RLV/~<name>
320 // to inventory folder versioning allowing the viewer to move the received folder itself as happens on the 320 // to the requested folder, which in this case is #RLV. However, it is the viewer that appears to be
321 // LL grid. Doing it again server-side then wrongly does a second create and move 321 // response from renaming the #RLV/~example folder to ~example. For some reason this is not yet
322// // XXX: This code was placed here to try and accomdate RLV which moves given folders named #RLV/~<name> 322 // happening, possibly because we are not sending the correct inventory update messages with the correct
323// // to a folder called name in #RLV. However, this approach may not be ultimately correct - from analysis 323 // transaction IDs
324// // of Firestorm 4.2.2 on sending an InventoryOffered instead of TaskInventoryOffered (as was previously 324 else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
325// // done), the viewer itself would appear to move and rename the folder, rather than the simulator doing it here. 325 {
326// else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) 326 UUID destinationFolderID = UUID.Zero;
327// { 327
328// UUID destinationFolderID = UUID.Zero; 328 if (im.binaryBucket != null && im.binaryBucket.Length >= 16)
329// 329 {
330// if (im.binaryBucket != null && im.binaryBucket.Length >= 16) 330 destinationFolderID = new UUID(im.binaryBucket, 0);
331// { 331 }
332// destinationFolderID = new UUID(im.binaryBucket, 0); 332
333// } 333 if (destinationFolderID != UUID.Zero)
334// 334 {
335// if (destinationFolderID != UUID.Zero) 335 InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId);
336// { 336 if (destinationFolder == null)
337// InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); 337 {
338// if (destinationFolder == null) 338 m_log.WarnFormat(
339// { 339 "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist",
340// m_log.WarnFormat( 340 client.Name, scene.Name, destinationFolderID);
341// "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", 341
342// client.Name, scene.Name, destinationFolderID); 342 return;
343// 343 }
344// return; 344
345// } 345 IInventoryService invService = scene.InventoryService;
346// 346
347// IInventoryService invService = scene.InventoryService; 347 UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
348// 348
349// UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip 349 InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId);
350// 350 item = invService.GetItem(item);
351// InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); 351 InventoryFolderBase folder = null;
352// item = invService.GetItem(item); 352 UUID? previousParentFolderID = null;
353// InventoryFolderBase folder = null; 353
354// UUID? previousParentFolderID = null; 354 if (item != null) // It's an item
355// 355 {
356// if (item != null) // It's an item 356 previousParentFolderID = item.Folder;
357// { 357 item.Folder = destinationFolderID;
358// previousParentFolderID = item.Folder; 358
359// item.Folder = destinationFolderID; 359 invService.DeleteItems(item.Owner, new List<UUID>() { item.ID });
360// 360 scene.AddInventoryItem(client, item);
361// invService.DeleteItems(item.Owner, new List<UUID>() { item.ID }); 361 }
362// scene.AddInventoryItem(client, item); 362 else
363// } 363 {
364// else 364 folder = new InventoryFolderBase(inventoryID, client.AgentId);
365// { 365 folder = invService.GetFolder(folder);
366// folder = new InventoryFolderBase(inventoryID, client.AgentId); 366
367// folder = invService.GetFolder(folder); 367 if (folder != null) // It's a folder
368// 368 {
369// if (folder != null) // It's a folder 369 previousParentFolderID = folder.ParentID;
370// { 370 folder.ParentID = destinationFolderID;
371// previousParentFolderID = folder.ParentID; 371 invService.MoveFolder(folder);
372// folder.ParentID = destinationFolderID; 372 }
373// invService.MoveFolder(folder); 373 }
374// } 374
375// } 375 // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code).
376// 376 if (previousParentFolderID != null)
377// // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). 377 {
378// if (previousParentFolderID != null) 378 InventoryFolderBase previousParentFolder
379// { 379 = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId);
380// InventoryFolderBase previousParentFolder 380 previousParentFolder = invService.GetFolder(previousParentFolder);
381// = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); 381 scene.SendInventoryUpdate(client, previousParentFolder, true, true);
382// previousParentFolder = invService.GetFolder(previousParentFolder); 382
383// scene.SendInventoryUpdate(client, previousParentFolder, true, true); 383 scene.SendInventoryUpdate(client, destinationFolder, true, true);
384// 384 }
385// scene.SendInventoryUpdate(client, destinationFolder, true, true); 385 }
386// } 386 }
387// }
388// }
389 else if ( 387 else if (
390 im.dialog == (byte)InstantMessageDialog.InventoryDeclined 388 im.dialog == (byte)InstantMessageDialog.InventoryDeclined
391 || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined) 389 || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined)
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index 232a4fe..6c9fd86 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -65,7 +65,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
65 { 65 {
66 m_Enabled = true; 66 m_Enabled = true;
67 67
68 m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty); 68 m_ThisGridURL = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
69 new string[] { "Startup", "Hypergrid", "Messaging" }, String.Empty);
70 // Legacy. Remove soon!
71 m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", m_ThisGridURL);
69 m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); 72 m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
70 } 73 }
71 } 74 }
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
new file mode 100644
index 0000000..1f1568f
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
@@ -0,0 +1,119 @@
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 log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.Packets;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Region.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41
42namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
43{
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")]
45 public class DAExampleModule : INonSharedRegionModule
46 {
47// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private static readonly bool ENABLED = false; // enable for testing
50
51 public const string DANamespace = "DAExample Module";
52
53 protected Scene m_scene;
54 protected IDialogModule m_dialogMod;
55
56 public string Name { get { return "DAExample Module"; } }
57 public Type ReplaceableInterface { get { return null; } }
58
59 public void Initialise(IConfigSource source) {}
60
61 public void AddRegion(Scene scene)
62 {
63 if (ENABLED)
64 {
65 m_scene = scene;
66 m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove;
67 m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>();
68 }
69 }
70
71 public void RemoveRegion(Scene scene)
72 {
73 if (ENABLED)
74 {
75 m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
76 }
77 }
78
79 public void RegionLoaded(Scene scene) {}
80
81 public void Close()
82 {
83 RemoveRegion(m_scene);
84 }
85
86 protected bool OnSceneGroupMove(UUID groupId, Vector3 delta)
87 {
88 OSDMap attrs = null;
89 SceneObjectPart sop = m_scene.GetSceneObjectPart(groupId);
90
91 if (sop == null)
92 return true;
93
94 if (!sop.DynAttrs.TryGetValue(DANamespace, out attrs))
95 attrs = new OSDMap();
96
97 OSDInteger newValue;
98
99 // We have to lock on the entire dynamic attributes map to avoid race conditions with serialization code.
100 lock (sop.DynAttrs)
101 {
102 if (!attrs.ContainsKey("moves"))
103 newValue = new OSDInteger(1);
104 else
105 newValue = new OSDInteger(attrs["moves"].AsInteger() + 1);
106
107 attrs["moves"] = newValue;
108
109 sop.DynAttrs[DANamespace] = attrs;
110 }
111
112 sop.ParentGroup.HasGroupChanged = true;
113
114 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue));
115
116 return true;
117 }
118 }
119} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
new file mode 100644
index 0000000..650aa35
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
@@ -0,0 +1,139 @@
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 log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.Packets;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Region.Framework;
39using OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42
43namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
44{
45 /// <summary>
46 /// Example module for experimenting with and demonstrating dynamic object ideas.
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DOExampleModule")]
49 public class DOExampleModule : INonSharedRegionModule
50 {
51 public class MyObject
52 {
53 public int Moves { get; set; }
54
55 public MyObject(int moves)
56 {
57 Moves = moves;
58 }
59 }
60
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62
63 private static readonly bool ENABLED = false; // enable for testing
64
65 private Scene m_scene;
66 private IDialogModule m_dialogMod;
67
68 public string Name { get { return "DOExample Module"; } }
69 public Type ReplaceableInterface { get { return null; } }
70
71 public void Initialise(IConfigSource source) {}
72
73 public void AddRegion(Scene scene)
74 {
75 if (ENABLED)
76 {
77 m_scene = scene;
78 m_scene.EventManager.OnObjectAddedToScene += OnObjectAddedToScene;
79 m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove;
80 m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>();
81 }
82 }
83
84 public void RemoveRegion(Scene scene)
85 {
86 if (ENABLED)
87 {
88 m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
89 }
90 }
91
92 public void RegionLoaded(Scene scene) {}
93
94 public void Close()
95 {
96 RemoveRegion(m_scene);
97 }
98
99 private void OnObjectAddedToScene(SceneObjectGroup so)
100 {
101 SceneObjectPart rootPart = so.RootPart;
102
103 OSDMap attrs;
104
105 int movesSoFar = 0;
106
107// Console.WriteLine("Here for {0}", so.Name);
108
109 if (rootPart.DynAttrs.TryGetValue(DAExampleModule.DANamespace, out attrs))
110 {
111 movesSoFar = attrs["moves"].AsInteger();
112
113 m_log.DebugFormat(
114 "[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name);
115 }
116
117 rootPart.DynObjs.Add(Name, new MyObject(movesSoFar));
118 }
119
120 private bool OnSceneGroupMove(UUID groupId, Vector3 delta)
121 {
122 SceneObjectGroup so = m_scene.GetSceneObjectGroup(groupId);
123
124 if (so == null)
125 return true;
126
127 object rawObj = so.RootPart.DynObjs.Get(Name);
128
129 if (rawObj != null)
130 {
131 MyObject myObj = (MyObject)rawObj;
132
133 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", so.Name, so.UUID, ++myObj.Moves));
134 }
135
136 return true;
137 }
138 }
139} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index ac4d93d..25334b9 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -66,6 +66,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
66 /// </summary> 66 /// </summary>
67 public bool WaitForAgentArrivedAtDestination { get; set; } 67 public bool WaitForAgentArrivedAtDestination { get; set; }
68 68
69 /// <summary>
70 /// If true then we ask the viewer to disable teleport cancellation and ignore teleport requests.
71 /// </summary>
72 /// <remarks>
73 /// This is useful in situations where teleport is very likely to always succeed and we want to avoid a
74 /// situation where avatars can be come 'stuck' due to a failed teleport cancellation. Unfortunately, the
75 /// nature of the teleport protocol makes it extremely difficult (maybe impossible) to make teleport
76 /// cancellation consistently suceed.
77 /// </remarks>
78 public bool DisableInterRegionTeleportCancellation { get; set; }
79
69 protected bool m_Enabled = false; 80 protected bool m_Enabled = false;
70 81
71 public Scene Scene { get; private set; } 82 public Scene Scene { get; private set; }
@@ -116,6 +127,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
116 IConfig transferConfig = source.Configs["EntityTransfer"]; 127 IConfig transferConfig = source.Configs["EntityTransfer"];
117 if (transferConfig != null) 128 if (transferConfig != null)
118 { 129 {
130 DisableInterRegionTeleportCancellation
131 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false);
132
119 WaitForAgentArrivedAtDestination 133 WaitForAgentArrivedAtDestination
120 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); 134 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault);
121 135
@@ -150,6 +164,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
150 { 164 {
151 client.OnTeleportHomeRequest += TriggerTeleportHome; 165 client.OnTeleportHomeRequest += TriggerTeleportHome;
152 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 166 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
167
168 if (!DisableInterRegionTeleportCancellation)
169 client.OnTeleportCancel += OnClientCancelTeleport;
170
171 client.OnConnectionClosed += OnConnectionClosed;
153 } 172 }
154 173
155 public virtual void Close() {} 174 public virtual void Close() {}
@@ -168,6 +187,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
168 187
169 #region Agent Teleports 188 #region Agent Teleports
170 189
190 private void OnConnectionClosed(IClientAPI client)
191 {
192 if (client.IsLoggingOut)
193 {
194 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
195
196 m_log.DebugFormat(
197 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
198 client.Name, Scene.Name);
199 }
200 }
201
202 private void OnClientCancelTeleport(IClientAPI client)
203 {
204 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling);
205
206 m_log.DebugFormat(
207 "[ENTITY TRANSFER MODULE]: Received teleport cancel request from {0} in {1}", client.Name, Scene.Name);
208 }
209
171 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) 210 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags)
172 { 211 {
173 if (sp.Scene.Permissions.IsGridGod(sp.UUID)) 212 if (sp.Scene.Permissions.IsGridGod(sp.UUID))
@@ -179,13 +218,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
179 if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) 218 if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
180 return; 219 return;
181 220
182 // Reset animations; the viewer does that in teleports.
183 sp.Animator.ResetAnimations();
184
185 string destinationRegionName = "(not found)"; 221 string destinationRegionName = "(not found)";
186 222
223 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection
224 // of whether the destination region completes the teleport.
225 if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
226 {
227 m_log.DebugFormat(
228 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.",
229 sp.Name, sp.UUID, position, regionHandle);
230
231 return;
232 }
233
187 try 234 try
188 { 235 {
236 // Reset animations; the viewer does that in teleports.
237 sp.Animator.ResetAnimations();
238
189 if (regionHandle == sp.Scene.RegionInfo.RegionHandle) 239 if (regionHandle == sp.Scene.RegionInfo.RegionHandle)
190 { 240 {
191 destinationRegionName = sp.Scene.RegionInfo.RegionName; 241 destinationRegionName = sp.Scene.RegionInfo.RegionName;
@@ -194,12 +244,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
194 } 244 }
195 else // Another region possibly in another simulator 245 else // Another region possibly in another simulator
196 { 246 {
197 GridRegion finalDestination; 247 GridRegion finalDestination = null;
198 TeleportAgentToDifferentRegion( 248 try
199 sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); 249 {
200 250 TeleportAgentToDifferentRegion(
201 if (finalDestination != null) 251 sp, regionHandle, position, lookAt, teleportFlags, out finalDestination);
202 destinationRegionName = finalDestination.RegionName; 252 }
253 finally
254 {
255 if (finalDestination != null)
256 destinationRegionName = finalDestination.RegionName;
257 }
203 } 258 }
204 } 259 }
205 catch (Exception e) 260 catch (Exception e)
@@ -209,11 +264,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
209 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, 264 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName,
210 e.Message, e.StackTrace); 265 e.Message, e.StackTrace);
211 266
212 // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail.
213 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
214
215 sp.ControllingClient.SendTeleportFailed("Internal error"); 267 sp.ControllingClient.SendTeleportFailed("Internal error");
216 } 268 }
269 finally
270 {
271 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
272 }
217 } 273 }
218 274
219 /// <summary> 275 /// <summary>
@@ -229,15 +285,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
229 "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", 285 "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}",
230 sp.Name, position, sp.Scene.RegionInfo.RegionName); 286 sp.Name, position, sp.Scene.RegionInfo.RegionName);
231 287
232 if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
233 {
234 m_log.DebugFormat(
235 "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.",
236 sp.Name, sp.UUID, position);
237
238 return;
239 }
240
241 // Teleport within the same region 288 // Teleport within the same region
242 if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) 289 if (IsOutsideRegion(sp.Scene, position) || position.Z < 0)
243 { 290 {
@@ -286,7 +333,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
286 } 333 }
287 334
288 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 335 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
289 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
290 } 336 }
291 337
292 /// <summary> 338 /// <summary>
@@ -340,7 +386,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
340 // 386 //
341 // This is it 387 // This is it
342 // 388 //
343 DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags); 389 DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
344 // 390 //
345 // 391 //
346 // 392 //
@@ -395,27 +441,54 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
395 && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; 441 && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
396 } 442 }
397 443
444 /// <summary>
445 /// Wraps DoTeleportInternal() and manages the transfer state.
446 /// </summary>
398 public void DoTeleport( 447 public void DoTeleport(
399 ScenePresence sp, GridRegion reg, GridRegion finalDestination, 448 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
400 Vector3 position, Vector3 lookAt, uint teleportFlags) 449 Vector3 position, Vector3 lookAt, uint teleportFlags)
401 { 450 {
402 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection 451 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection
403 // of whether the destination region completes the teleport. 452 // of whether the destination region completes the teleport.
404 m_entityTransferStateMachine.SetInTransit(sp.UUID); 453 if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
405// if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) 454 {
406// { 455 m_log.DebugFormat(
407// m_log.DebugFormat( 456 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.",
408// "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", 457 sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
409// sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
410//
411// return;
412// }
413 458
414 if (reg == null || finalDestination == null) 459 return;
460 }
461
462 try
463 {
464 DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
465 }
466 catch (Exception e)
467 {
468 m_log.ErrorFormat(
469 "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}",
470 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, finalDestination.RegionName,
471 e.Message, e.StackTrace);
472
473 sp.ControllingClient.SendTeleportFailed("Internal error");
474 }
475 finally
415 { 476 {
416 sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
417 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 477 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
478 }
479 }
418 480
481 /// <summary>
482 /// Teleports the agent to another region.
483 /// This method doesn't manage the transfer state; the caller must do that.
484 /// </summary>
485 private void DoTeleportInternal(
486 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
487 Vector3 position, Vector3 lookAt, uint teleportFlags)
488 {
489 if (reg == null || finalDestination == null)
490 {
491 sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
419 return; 492 return;
420 } 493 }
421 494
@@ -435,8 +508,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
435 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, 508 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
436 MaxTransferDistance)); 509 MaxTransferDistance));
437 510
438 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
439
440 return; 511 return;
441 } 512 }
442 513
@@ -454,7 +525,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
454 if (endPoint == null || endPoint.Address == null) 525 if (endPoint == null || endPoint.Address == null)
455 { 526 {
456 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 527 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
457 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
458 528
459 return; 529 return;
460 } 530 }
@@ -464,19 +534,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
464 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", 534 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
465 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); 535 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
466 536
467// if (!sp.ValidateAttachments())
468// {
469// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
470// return;
471// }
472
473 string reason; 537 string reason;
474 string version; 538 string version;
475 if (!Scene.SimulationService.QueryAccess( 539 if (!Scene.SimulationService.QueryAccess(
476 finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) 540 finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason))
477 { 541 {
478 sp.ControllingClient.SendTeleportFailed(reason); 542 sp.ControllingClient.SendTeleportFailed(reason);
479 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
480 543
481 m_log.DebugFormat( 544 m_log.DebugFormat(
482 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", 545 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}",
@@ -494,6 +557,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
494 else if (sp.Flying) 557 else if (sp.Flying)
495 teleportFlags |= (uint)TeleportFlags.IsFlying; 558 teleportFlags |= (uint)TeleportFlags.IsFlying;
496 559
560 if (DisableInterRegionTeleportCancellation)
561 teleportFlags |= (uint)TeleportFlags.DisableCancel;
562
497 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to 563 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
498 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). 564 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
499 sp.ControllingClient.SendTeleportStart(teleportFlags); 565 sp.ControllingClient.SendTeleportStart(teleportFlags);
@@ -530,11 +596,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
530 } 596 }
531 597
532 // Let's create an agent there if one doesn't exist yet. 598 // Let's create an agent there if one doesn't exist yet.
599 // NOTE: logout will always be false for a non-HG teleport.
533 bool logout = false; 600 bool logout = false;
534 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) 601 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
535 { 602 {
536 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); 603 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
537 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
538 604
539 m_log.DebugFormat( 605 m_log.DebugFormat(
540 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", 606 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
@@ -543,6 +609,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
543 return; 609 return;
544 } 610 }
545 611
612 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
613 {
614 m_log.DebugFormat(
615 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
616 sp.Name, finalDestination.RegionName, sp.Scene.Name);
617
618 return;
619 }
620 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
621 {
622 m_log.DebugFormat(
623 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
624 sp.Name, finalDestination.RegionName, sp.Scene.Name);
625
626 return;
627 }
628
546 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 629 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
547 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 630 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
548 631
@@ -564,11 +647,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
564 647
565 if (m_eqModule != null) 648 if (m_eqModule != null)
566 { 649 {
650 // The EnableSimulator message makes the client establish a connection with the destination
651 // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the
652 // correct circuit code.
567 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); 653 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID);
568 654
569 // ES makes the client send a UseCircuitCode message to the destination, 655 // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination
570 // which triggers a bunch of things there. 656 // simulator to confirm that it has established communication with the viewer.
571 // So let's wait
572 Thread.Sleep(200); 657 Thread.Sleep(200);
573 658
574 // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears 659 // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears
@@ -579,6 +664,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
579 } 664 }
580 else 665 else
581 { 666 {
667 // XXX: This is a little misleading since we're information the client of its avatar destination,
668 // which may or may not be a neighbour region of the source region. This path is probably little
669 // used anyway (with EQ being the one used). But it is currently being used for test code.
582 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); 670 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
583 } 671 }
584 } 672 }
@@ -596,23 +684,60 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
596 684
597 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); 685 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
598 686
687 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
688 // establish th econnection to the destination which makes it return true.
689 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
690 {
691 m_log.DebugFormat(
692 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
693 sp.Name, finalDestination.RegionName, sp.Scene.Name);
694
695 return;
696 }
697
698 // A common teleport failure occurs when we can send CreateAgent to the
699 // destination region but the viewer cannot establish the connection (e.g. due to network issues between
700 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
701 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
599 if (!UpdateAgent(reg, finalDestination, agent, sp)) 702 if (!UpdateAgent(reg, finalDestination, agent, sp))
600 { 703 {
601 // Region doesn't take it 704 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
705 {
706 m_log.DebugFormat(
707 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
708 sp.Name, finalDestination.RegionName, sp.Scene.Name);
709
710 return;
711 }
712
602 m_log.WarnFormat( 713 m_log.WarnFormat(
603 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", 714 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
604 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 715 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
605 716
606 Fail(sp, finalDestination, logout); 717 Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established.");
607 return; 718 return;
608 } 719 }
609 720
610 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); 721 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
722 {
723 m_log.DebugFormat(
724 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
725 sp.Name, finalDestination.RegionName, sp.Scene.Name);
726
727 CleanupFailedInterRegionTeleport(sp, finalDestination);
728
729 return;
730 }
611 731
612 m_log.DebugFormat( 732 m_log.DebugFormat(
613 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", 733 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
614 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); 734 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
615 735
736 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
737 // where that neighbour simulator could otherwise request a child agent create on the source which then
738 // closes our existing agent which is still signalled as root.
739 sp.IsChildAgent = true;
740
616 if (m_eqModule != null) 741 if (m_eqModule != null)
617 { 742 {
618 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); 743 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID);
@@ -623,19 +748,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
623 teleportFlags, capsPath); 748 teleportFlags, capsPath);
624 } 749 }
625 750
626 // Let's set this to true tentatively. This does not trigger OnChildAgent
627 sp.IsChildAgent = true;
628
629 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which 751 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
630 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation 752 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
631 // that the client contacted the destination before we close things here. 753 // that the client contacted the destination before we close things here.
632 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) 754 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID))
633 { 755 {
756 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
757 {
758 m_log.DebugFormat(
759 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
760 sp.Name, finalDestination.RegionName, sp.Scene.Name);
761
762 return;
763 }
764
634 m_log.WarnFormat( 765 m_log.WarnFormat(
635 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", 766 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
636 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 767 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
637 768
638 Fail(sp, finalDestination, logout); 769 Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion.");
639 return; 770 return;
640 } 771 }
641 772
@@ -658,8 +789,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
658 // Now let's make it officially a child agent 789 // Now let's make it officially a child agent
659 sp.MakeChildAgent(); 790 sp.MakeChildAgent();
660 791
661// sp.Scene.CleanDroppedAttachments();
662
663 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 792 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
664 793
665 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 794 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
@@ -688,18 +817,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
688// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", 817// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
689// sp.UUID); 818// sp.UUID);
690// } 819// }
691
692 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
693 } 820 }
694 821
695 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) 822 /// <summary>
823 /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation.
824 /// </summary>
825 /// <remarks>
826 /// All operations here must be idempotent so that we can call this method at any point in the teleport process
827 /// up until we send the TeleportFinish event quene event to the viewer.
828 /// <remarks>
829 /// <param name='sp'> </param>
830 /// <param name='finalDestination'></param>
831 protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
696 { 832 {
697 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 833 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
698 834
699 // Client never contacted destination. Let's restore everything back
700 sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
701
702 // Fail. Reset it back
703 sp.IsChildAgent = false; 835 sp.IsChildAgent = false;
704 ReInstantiateScripts(sp); 836 ReInstantiateScripts(sp);
705 837
@@ -707,10 +839,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
707 839
708 // Finally, kill the agent we just created at the destination. 840 // Finally, kill the agent we just created at the destination.
709 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); 841 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID);
842 }
710 843
711 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); 844 /// <summary>
845 /// Signal that the inter-region teleport failed and perform cleanup.
846 /// </summary>
847 /// <param name='sp'></param>
848 /// <param name='finalDestination'></param>
849 /// <param name='logout'></param>
850 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
851 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason)
852 {
853 CleanupFailedInterRegionTeleport(sp, finalDestination);
854
855 sp.ControllingClient.SendTeleportFailed(
856 string.Format(
857 "Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason));
712 858
713 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 859 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
714 } 860 }
715 861
716 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) 862 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
@@ -1101,10 +1247,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1101 bool isFlying, string version) 1247 bool isFlying, string version)
1102 { 1248 {
1103 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) 1249 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1250 {
1251 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1104 return agent; 1252 return agent;
1253 }
1105 1254
1106 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) 1255 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1256 {
1257 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1107 return agent; 1258 return agent;
1259 }
1108 1260
1109 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version); 1261 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1110 return agent; 1262 return agent;
@@ -1131,9 +1283,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1131 // region doesn't take it 1283 // region doesn't take it
1132 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1284 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1133 1285
1286 m_log.WarnFormat(
1287 "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.",
1288 neighbourRegion.RegionName, agent.Name);
1289
1134 ReInstantiateScripts(agent); 1290 ReInstantiateScripts(agent);
1135 agent.AddToPhysicalScene(isFlying); 1291 agent.AddToPhysicalScene(isFlying);
1136 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1137 1292
1138 return false; 1293 return false;
1139 } 1294 }
@@ -2048,7 +2203,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2048 2203
2049 public bool IsInTransit(UUID id) 2204 public bool IsInTransit(UUID id)
2050 { 2205 {
2051 return m_entityTransferStateMachine.IsInTransit(id); 2206 return m_entityTransferStateMachine.GetAgentTransferState(id) != null;
2052 } 2207 }
2053 2208
2054 protected void ReInstantiateScripts(ScenePresence sp) 2209 protected void ReInstantiateScripts(ScenePresence sp)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index 70dd1bc..e903383 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -51,10 +51,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
51 /// This is a state machine. 51 /// This is a state machine.
52 /// 52 ///
53 /// [Entry] => Preparing 53 /// [Entry] => Preparing
54 /// Preparing => { Transferring || CleaningUp || [Exit] } 54 /// Preparing => { Transferring || Cancelling || CleaningUp || Aborting || [Exit] }
55 /// Transferring => { ReceivedAtDestination || CleaningUp } 55 /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp || Aborting }
56 /// ReceivedAtDestination => CleaningUp 56 /// Cancelling => CleaningUp || Aborting
57 /// ReceivedAtDestination => CleaningUp || Aborting
57 /// CleaningUp => [Exit] 58 /// CleaningUp => [Exit]
59 /// Aborting => [Exit]
58 /// 60 ///
59 /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp 61 /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp
60 /// However, any state can transition to CleaningUp if the teleport has failed. 62 /// However, any state can transition to CleaningUp if the teleport has failed.
@@ -64,7 +66,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
64 Preparing, // The agent is being prepared for transfer 66 Preparing, // The agent is being prepared for transfer
65 Transferring, // The agent is in the process of being transferred to a destination 67 Transferring, // The agent is in the process of being transferred to a destination
66 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received 68 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
67 CleaningUp // The agent is being changed to child/removed after a transfer 69 CleaningUp, // The agent is being changed to child/removed after a transfer
70 Cancelling, // The user has cancelled the teleport but we have yet to act upon this.
71 Aborting // The transfer is aborting. Unlike Cancelling, no compensating actions should be performed
68 } 72 }
69 73
70 /// <summary> 74 /// <summary>
@@ -115,42 +119,114 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
115 /// <param name='newState'></param> 119 /// <param name='newState'></param>
116 /// <returns></returns> 120 /// <returns></returns>
117 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> 121 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
118 internal void UpdateInTransit(UUID id, AgentTransferState newState) 122 internal bool UpdateInTransit(UUID id, AgentTransferState newState)
119 { 123 {
124 bool transitionOkay = false;
125
126 // We don't want to throw an exception on cancel since this can come it at any time.
127 bool failIfNotOkay = true;
128
129 // Should be a failure message if failure is not okay.
130 string failureMessage = null;
131
132 AgentTransferState? oldState = null;
133
120 lock (m_agentsInTransit) 134 lock (m_agentsInTransit)
121 { 135 {
122 // Illegal to try and update an agent that's not actually in transit. 136 // Illegal to try and update an agent that's not actually in transit.
123 if (!m_agentsInTransit.ContainsKey(id)) 137 if (!m_agentsInTransit.ContainsKey(id))
124 throw new Exception( 138 {
125 string.Format( 139 if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting)
126 "Agent with ID {0} is not registered as in transit in {1}", 140 failureMessage = string.Format(
127 id, m_mod.Scene.RegionInfo.RegionName)); 141 "Agent with ID {0} is not registered as in transit in {1}",
128 142 id, m_mod.Scene.RegionInfo.RegionName);
129 AgentTransferState oldState = m_agentsInTransit[id]; 143 else
144 failIfNotOkay = false;
145 }
146 else
147 {
148 oldState = m_agentsInTransit[id];
130 149
131 bool transitionOkay = false; 150 if (newState == AgentTransferState.Aborting)
151 {
152 transitionOkay = true;
153 }
154 else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
155 {
156 transitionOkay = true;
157 }
158 else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
159 {
160 transitionOkay = true;
161 }
162 else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
163 {
164 transitionOkay = true;
165 }
166 else
167 {
168 if (newState == AgentTransferState.Cancelling
169 && (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring))
170 {
171 transitionOkay = true;
172 }
173 else
174 {
175 failIfNotOkay = false;
176 }
177 }
132 178
133 if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) 179 if (!transitionOkay)
134 transitionOkay = true; 180 failureMessage
135 else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) 181 = string.Format(
136 transitionOkay = true; 182 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
137 else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) 183 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName);
138 transitionOkay = true; 184 }
139 185
140 if (transitionOkay) 186 if (transitionOkay)
187 {
141 m_agentsInTransit[id] = newState; 188 m_agentsInTransit[id] = newState;
142 else 189
143 throw new Exception( 190// m_log.DebugFormat(
144 string.Format( 191// "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}",
145 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", 192// id, oldState, newState, m_mod.Scene.Name);
146 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName)); 193 }
194 else if (failIfNotOkay)
195 {
196 throw new Exception(failureMessage);
197 }
198// else
199// {
200// if (oldState != null)
201// m_log.DebugFormat(
202// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}",
203// id, oldState, newState, m_mod.Scene.Name);
204// else
205// m_log.DebugFormat(
206// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit",
207// id, newState, m_mod.Scene.Name);
208// }
147 } 209 }
210
211 return transitionOkay;
148 } 212 }
149 213
150 internal bool IsInTransit(UUID id) 214 /// <summary>
215 /// Gets the current agent transfer state.
216 /// </summary>
217 /// <returns>Null if the agent is not in transit</returns>
218 /// <param name='id'>
219 /// Identifier.
220 /// </param>
221 internal AgentTransferState? GetAgentTransferState(UUID id)
151 { 222 {
152 lock (m_agentsInTransit) 223 lock (m_agentsInTransit)
153 return m_agentsInTransit.ContainsKey(id); 224 {
225 if (!m_agentsInTransit.ContainsKey(id))
226 return null;
227 else
228 return m_agentsInTransit[id];
229 }
154 } 230 }
155 231
156 /// <summary> 232 /// <summary>
@@ -203,14 +279,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
203 279
204 lock (m_agentsInTransit) 280 lock (m_agentsInTransit)
205 { 281 {
206 if (!IsInTransit(id)) 282 AgentTransferState? currentState = GetAgentTransferState(id);
283
284 if (currentState == null)
207 throw new Exception( 285 throw new Exception(
208 string.Format( 286 string.Format(
209 "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit", 287 "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit",
210 id, m_mod.Scene.RegionInfo.RegionName)); 288 id, m_mod.Scene.RegionInfo.RegionName));
211 289
212 AgentTransferState currentState = m_agentsInTransit[id];
213
214 if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) 290 if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination)
215 throw new Exception( 291 throw new Exception(
216 string.Format( 292 string.Format(
@@ -222,8 +298,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
222 298
223 // There should be no race condition here since no other code should be removing the agent transfer or 299 // There should be no race condition here since no other code should be removing the agent transfer or
224 // changing the state to another other than Transferring => ReceivedAtDestination. 300 // changing the state to another other than Transferring => ReceivedAtDestination.
225 while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) 301
302 while (count-- > 0)
226 { 303 {
304 lock (m_agentsInTransit)
305 {
306 if (m_agentsInTransit[id] == AgentTransferState.ReceivedAtDestination)
307 break;
308 }
309
227// m_log.Debug(" >>> Waiting... " + count); 310// m_log.Debug(" >>> Waiting... " + count);
228 Thread.Sleep(100); 311 Thread.Sleep(100);
229 } 312 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index f3a0b01..9b78b3b 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -212,11 +212,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
212 protected override GridRegion GetFinalDestination(GridRegion region) 212 protected override GridRegion GetFinalDestination(GridRegion region)
213 { 213 {
214 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID); 214 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID);
215 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); 215 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionName, flags);
216 216
217 if ((flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) 217 if ((flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
218 { 218 {
219 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); 219 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region is hyperlink");
220 GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID); 220 GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID);
221 if (real_destination != null) 221 if (real_destination != null)
222 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: GetFinalDestination serveruri -> {0}", real_destination.ServerURI); 222 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: GetFinalDestination serveruri -> {0}", real_destination.ServerURI);
diff --git a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs
index 4004135..b9786ae 100644
--- a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs
+++ b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenSim.Region.Framework.Interfaces; 30using OpenSim.Region.Framework.Interfaces;
31using OpenMetaverse;
31 32
32namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander 33namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
33{ 34{
@@ -152,6 +153,9 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
152 case "Boolean": 153 case "Boolean":
153 m_args[i].ArgumentValue = Boolean.Parse(arg.ToString()); 154 m_args[i].ArgumentValue = Boolean.Parse(arg.ToString());
154 break; 155 break;
156 case "UUID":
157 m_args[i].ArgumentValue = UUID.Parse(arg.ToString());
158 break;
155 default: 159 default:
156 Console.WriteLine("ERROR: Unknown desired type for argument " + m_args[i].Name + " on command " + m_name); 160 Console.WriteLine("ERROR: Unknown desired type for argument " + m_args[i].Name + " on command " + m_name);
157 break; 161 break;
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index f8ec6de..7871eda 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -71,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
71 71
72 #region Internal functions 72 #region Internal functions
73 73
74 public AssetMetadata FetchMetadata(string url, UUID assetID) 74 private AssetMetadata FetchMetadata(string url, UUID assetID)
75 { 75 {
76 if (!url.EndsWith("/") && !url.EndsWith("=")) 76 if (!url.EndsWith("/") && !url.EndsWith("="))
77 url = url + "/"; 77 url = url + "/";
@@ -86,6 +86,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
86 return meta; 86 return meta;
87 } 87 }
88 88
89 private AssetBase FetchAsset(string url, UUID assetID)
90 {
91 // Test if it's already here
92 AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
93 if (asset == null)
94 {
95 if (!url.EndsWith("/") && !url.EndsWith("="))
96 url = url + "/";
97
98 asset = m_scene.AssetService.Get(url + assetID.ToString());
99
100 //if (asset != null)
101 // m_log.DebugFormat("[HG ASSET MAPPER]: Fetched asset {0} of type {1} from {2} ", assetID, asset.Metadata.Type, url);
102 //else
103 // m_log.DebugFormat("[HG ASSET MAPPER]: Unable to fetch asset {0} from {1} ", assetID, url);
104
105 }
106
107 return asset;
108 }
109
89 public bool PostAsset(string url, AssetBase asset) 110 public bool PostAsset(string url, AssetBase asset)
90 { 111 {
91 if (asset != null) 112 if (asset != null)
@@ -228,11 +249,22 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
228 if (meta == null) 249 if (meta == null)
229 return; 250 return;
230 251
231 // The act of gathering UUIDs downloads the assets from the remote server 252 // The act of gathering UUIDs downloads some assets from the remote server
253 // but not all...
232 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); 254 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>();
233 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); 255 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL);
234 uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids); 256 uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids);
235 257 m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count);
258 bool success = true;
259 foreach (UUID uuid in ids.Keys)
260 if (FetchAsset(userAssetURL, uuid) == null)
261 success = false;
262
263 // maybe all pieces got here...
264 if (!success)
265 m_log.DebugFormat("[HG ASSET MAPPER]: Problems getting item {0} from asset server {1}", assetID, userAssetURL);
266 else
267 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL);
236 } 268 }
237 269
238 270
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 964efda..b2b628d 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -88,12 +88,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
88 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; 88 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
89 if (thisModuleConfig != null) 89 if (thisModuleConfig != null)
90 { 90 {
91 // legacy configuration [obsolete] 91 m_HomeURI = Util.GetConfigVarFromSections<string>(source, "HomeURI",
92 m_HomeURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); 92 new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty);
93 // preferred 93 m_ThisGatekeeper = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI",
94 m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI); 94 new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty);
95 // Legacy. Renove soon!
96 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", m_ThisGatekeeper);
97
95 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); 98 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
96 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
97 m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true); 99 m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true);
98 } 100 }
99 else 101 else
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
index 21d8bd7..ad1a0e1 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
@@ -49,7 +49,7 @@ using OpenSim.Tests.Common.Mock;
49namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests 49namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
50{ 50{
51 [TestFixture] 51 [TestFixture]
52 public class InventoryAccessModuleTests 52 public class InventoryAccessModuleTests : OpenSimTestCase
53 { 53 {
54 protected TestScene m_scene; 54 protected TestScene m_scene;
55 protected BasicInventoryAccessModule m_iam; 55 protected BasicInventoryAccessModule m_iam;
@@ -57,8 +57,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
57 protected TestClient m_tc; 57 protected TestClient m_tc;
58 58
59 [SetUp] 59 [SetUp]
60 public void SetUp() 60 public override void SetUp()
61 { 61 {
62 base.SetUp();
63
62 m_iam = new BasicInventoryAccessModule(); 64 m_iam = new BasicInventoryAccessModule();
63 65
64 IConfigSource config = new IniConfigSource(); 66 IConfigSource config = new IniConfigSource();
@@ -107,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
107 item1.AssetID = asset1.FullID; 109 item1.AssetID = asset1.FullID;
108 item1.ID = item1Id; 110 item1.ID = item1Id;
109 InventoryFolderBase objsFolder 111 InventoryFolderBase objsFolder
110 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; 112 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
111 item1.Folder = objsFolder.ID; 113 item1.Folder = objsFolder.ID;
112 m_scene.AddInventoryItem(item1); 114 m_scene.AddInventoryItem(item1);
113 115
@@ -157,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
157 item1.AssetID = asset1.FullID; 159 item1.AssetID = asset1.FullID;
158 item1.ID = item1Id; 160 item1.ID = item1Id;
159 InventoryFolderBase objsFolder 161 InventoryFolderBase objsFolder
160 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; 162 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
161 item1.Folder = objsFolder.ID; 163 item1.Folder = objsFolder.ID;
162 m_scene.AddInventoryItem(item1); 164 m_scene.AddInventoryItem(item1);
163 165
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index d84460a..64feec1 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -33,6 +33,7 @@ using log4net;
33using Nini.Config; 33using Nini.Config;
34using OpenMetaverse; 34using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Monitoring;
36using OpenSim.Framework.Servers; 37using OpenSim.Framework.Servers;
37using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts; 38using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts;
38using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors; 39using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors;
@@ -100,6 +101,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
100 "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName), StatsPage); 101 "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName), StatsPage);
101 102
102 AddMonitors(); 103 AddMonitors();
104 RegisterStatsManagerRegionStatistics();
103 } 105 }
104 106
105 public void RemoveRegion(Scene scene) 107 public void RemoveRegion(Scene scene)
@@ -109,6 +111,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
109 111
110 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + m_scene.RegionInfo.RegionID); 112 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + m_scene.RegionInfo.RegionID);
111 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName)); 113 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName));
114
115 UnRegisterStatsManagerRegionStatistics();
116
112 m_scene = null; 117 m_scene = null;
113 } 118 }
114 119
@@ -399,6 +404,45 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
399 { 404 {
400 m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")"); 405 m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")");
401 } 406 }
407
408 private List<Stat> registeredStats = new List<Stat>();
409 private void MakeStat(string pName, string pUnitName, Action<Stat> act)
410 {
411 Stat tempStat = new Stat(pName, pName, pName, pUnitName, "scene", m_scene.RegionInfo.RegionName, StatType.Pull, act, StatVerbosity.Info);
412 StatsManager.RegisterStat(tempStat);
413 registeredStats.Add(tempStat);
414 }
415 private void RegisterStatsManagerRegionStatistics()
416 {
417 MakeStat("RootAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetRootAgentCount(); });
418 MakeStat("ChildAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetChildAgentCount(); });
419 MakeStat("TotalPrims", "objects", (s) => { s.Value = m_scene.SceneGraph.GetTotalObjectsCount(); });
420 MakeStat("ActivePrims", "objects", (s) => { s.Value = m_scene.SceneGraph.GetActiveObjectsCount(); });
421 MakeStat("ActiveScripts", "scripts", (s) => { s.Value = m_scene.SceneGraph.GetActiveScriptsCount(); });
422
423 MakeStat("TimeDilation", "sec/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[0]; });
424 MakeStat("SimFPS", "fps", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[1]; });
425 MakeStat("PhysicsFPS", "fps", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[2]; });
426 MakeStat("AgentUpdates", "updates/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[3]; });
427 MakeStat("FrameTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[8]; });
428 MakeStat("NetTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[9]; });
429 MakeStat("OtherTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[12]; });
430 MakeStat("PhysicsTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[10]; });
431 MakeStat("AgentTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[16]; });
432 MakeStat("ImageTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[11]; });
433 MakeStat("ScriptLines", "lines/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[20]; });
434 MakeStat("SimSpareMS", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[21]; });
435 }
436
437 private void UnRegisterStatsManagerRegionStatistics()
438 {
439 foreach (Stat stat in registeredStats)
440 {
441 StatsManager.DeregisterStat(stat);
442 stat.Dispose();
443 }
444 registeredStats.Clear();
445 }
402 446
403 } 447 }
404} 448} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
index fb74cc6..f3436d1 100644
--- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
@@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
57 try 57 try
58 { 58 {
59 IConfig statConfig = source.Configs["Statistics.Binary"]; 59 IConfig statConfig = source.Configs["Statistics.Binary"];
60 if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled")) 60 if (statConfig != null && statConfig.Contains("enabled") && statConfig.GetBoolean("enabled"))
61 { 61 {
62 if (statConfig.Contains("collect_region_stats")) 62 if (statConfig.Contains("collect_region_stats"))
63 { 63 {
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs
index fd8d5e3..2fe9026 100755
--- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs
+++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
52 private TimeSpan m_logFileLife; 52 private TimeSpan m_logFileLife;
53 private DateTime m_logFileEndTime; 53 private DateTime m_logFileEndTime;
54 private Object m_logFileWriteLock = new Object(); 54 private Object m_logFileWriteLock = new Object();
55 private bool m_flushWrite;
55 56
56 // set externally when debugging. If let 'null', this does not write any error messages. 57 // set externally when debugging. If let 'null', this does not write any error messages.
57 public ILog ErrorLogger = null; 58 public ILog ErrorLogger = null;
@@ -73,7 +74,9 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
73 /// <param name="dir">The directory to create the log file in. May be 'null' for default.</param> 74 /// <param name="dir">The directory to create the log file in. May be 'null' for default.</param>
74 /// <param name="headr">The characters that begin the log file name. May be 'null' for default.</param> 75 /// <param name="headr">The characters that begin the log file name. May be 'null' for default.</param>
75 /// <param name="maxFileTime">Maximum age of a log file in minutes. If zero, will set default.</param> 76 /// <param name="maxFileTime">Maximum age of a log file in minutes. If zero, will set default.</param>
76 public LogWriter(string dir, string headr, int maxFileTime) 77 /// <param name="flushWrite">Whether to do a flush after every log write. Best left off but
78 /// if one is looking for a crash, this is a good thing to turn on.</param>
79 public LogWriter(string dir, string headr, int maxFileTime, bool flushWrite)
77 { 80 {
78 m_logDirectory = dir == null ? "." : dir; 81 m_logDirectory = dir == null ? "." : dir;
79 82
@@ -86,8 +89,14 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
86 m_logFileLife = new TimeSpan(0, m_logMaxFileTimeMin, 0); 89 m_logFileLife = new TimeSpan(0, m_logMaxFileTimeMin, 0);
87 m_logFileEndTime = DateTime.Now + m_logFileLife; 90 m_logFileEndTime = DateTime.Now + m_logFileLife;
88 91
92 m_flushWrite = flushWrite;
93
89 Enabled = true; 94 Enabled = true;
90 } 95 }
96 // Constructor that assumes flushWrite is off.
97 public LogWriter(string dir, string headr, int maxFileTime) : this(dir, headr, maxFileTime, false)
98 {
99 }
91 100
92 public void Dispose() 101 public void Dispose()
93 { 102 {
@@ -127,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
127 { 136 {
128 lock (m_logFileWriteLock) 137 lock (m_logFileWriteLock)
129 { 138 {
130 DateTime now = DateTime.Now; 139 DateTime now = DateTime.UtcNow;
131 if (m_logFile == null || now > m_logFileEndTime) 140 if (m_logFile == null || now > m_logFileEndTime)
132 { 141 {
133 if (m_logFile != null) 142 if (m_logFile != null)
@@ -153,6 +162,8 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
153 buff.Append(line); 162 buff.Append(line);
154 buff.Append("\r\n"); 163 buff.Append("\r\n");
155 m_logFile.Write(buff.ToString()); 164 m_logFile.Write(buff.ToString());
165 if (m_flushWrite)
166 m_logFile.Flush();
156 } 167 }
157 } 168 }
158 } 169 }
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 86e7004..77e8b00 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -181,6 +181,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
181 181
182 m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query); 182 m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query);
183 183
184 // searhc the user accounts service
184 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); 185 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
185 186
186 List<UserData> users = new List<UserData>(); 187 List<UserData> users = new List<UserData>();
@@ -196,6 +197,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
196 } 197 }
197 } 198 }
198 199
200 // search the local cache
201 foreach (UserData data in m_UserCache.Values)
202 if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null &&
203 (data.FirstName.StartsWith(query) || data.LastName.StartsWith(query)))
204 users.Add(data);
205
199 AddAdditionalUsers(avatarID, query, users); 206 AddAdditionalUsers(avatarID, query, users);
200 207
201 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); 208 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
@@ -433,6 +440,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
433 public void AddUser(UUID uuid, string first, string last, string homeURL) 440 public void AddUser(UUID uuid, string first, string last, string homeURL)
434 { 441 {
435 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL); 442 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
443 if (homeURL == string.Empty)
444 return;
445
436 AddUser(uuid, homeURL + ";" + first + " " + last); 446 AddUser(uuid, homeURL + ";" + first + " " + last);
437 } 447 }
438 448
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index ec94420..7b11658 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -52,8 +52,8 @@ namespace OpenSim.Region.CoreModules.Hypergrid
52 52
53 public override void Initialise(IConfigSource config) 53 public override void Initialise(IConfigSource config)
54 { 54 {
55 IConfig startupConfig = config.Configs["Startup"]; 55 if (Util.GetConfigVarFromSections<string>(
56 if (startupConfig.GetString("WorldMapModule", "WorldMap") == "HGWorldMap") 56 config, "WorldMapModule", new string[] { "Map", "Startup" }, "WorldMap") == "HGWorldMap")
57 m_Enabled = true; 57 m_Enabled = true;
58 } 58 }
59 59
diff --git a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs
index 5a8c4a2..bfe0383 100644
--- a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs
@@ -30,8 +30,8 @@ using Mono.Addins;
30// Build Number 30// Build Number
31// Revision 31// Revision
32// 32//
33[assembly: AssemblyVersion("0.7.5.*")] 33[assembly: AssemblyVersion("0.7.6.*")]
34[assembly: AssemblyFileVersion("1.0.0.0")] 34
35 35
36[assembly: Addin("OpenSim.Region.CoreModules", "0.1")] 36[assembly: Addin("OpenSim.Region.CoreModules", "0.1")]
37[assembly: AddinDependency("OpenSim", "0.5")] 37[assembly: AddinDependency("OpenSim", "0.5")]
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 24e925e..f2922d6 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -84,20 +84,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
84 private Dictionary<string, UrlData> m_UrlMap = 84 private Dictionary<string, UrlData> m_UrlMap =
85 new Dictionary<string, UrlData>(); 85 new Dictionary<string, UrlData>();
86 86
87 /// <summary> 87 private uint m_HttpsPort = 0;
88 /// Maximum number of external urls that can be set up by this module.
89 /// </summary>
90 private int m_TotalUrls = 15000;
91
92 private uint https_port = 0;
93 private IHttpServer m_HttpServer = null; 88 private IHttpServer m_HttpServer = null;
94 private IHttpServer m_HttpsServer = null; 89 private IHttpServer m_HttpsServer = null;
95 90
96 private string m_ExternalHostNameForLSL = ""; 91 public string ExternalHostNameForLSL { get; private set; }
97 public string ExternalHostNameForLSL 92
98 { 93 /// <summary>
99 get { return m_ExternalHostNameForLSL; } 94 /// The default maximum number of urls
100 } 95 /// </summary>
96 public const int DefaultTotalUrls = 15000;
97
98 /// <summary>
99 /// Maximum number of external urls that can be set up by this module.
100 /// </summary>
101 public int TotalUrls { get; set; }
101 102
102 public Type ReplaceableInterface 103 public Type ReplaceableInterface
103 { 104 {
@@ -111,17 +112,27 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
111 112
112 public void Initialise(IConfigSource config) 113 public void Initialise(IConfigSource config)
113 { 114 {
114 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); 115 IConfig networkConfig = config.Configs["Network"];
115 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); 116
116 if (ssl_enabled) 117 if (networkConfig != null)
117 { 118 {
118 https_port = (uint) config.Configs["Network"].GetInt("https_port",0); 119 ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", null);
120
121 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener", false);
122
123 if (ssl_enabled)
124 m_HttpsPort = (uint)config.Configs["Network"].GetInt("https_port", (int)m_HttpsPort);
119 } 125 }
120 126
127 if (ExternalHostNameForLSL == null)
128 ExternalHostNameForLSL = System.Environment.MachineName;
129
121 IConfig llFunctionsConfig = config.Configs["LL-Functions"]; 130 IConfig llFunctionsConfig = config.Configs["LL-Functions"];
122 131
123 if (llFunctionsConfig != null) 132 if (llFunctionsConfig != null)
124 m_TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", m_TotalUrls); 133 TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", DefaultTotalUrls);
134 else
135 TotalUrls = DefaultTotalUrls;
125 } 136 }
126 137
127 public void PostInitialise() 138 public void PostInitialise()
@@ -137,9 +148,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
137 m_HttpServer = MainServer.Instance; 148 m_HttpServer = MainServer.Instance;
138 // 149 //
139 // We can use the https if it is enabled 150 // We can use the https if it is enabled
140 if (https_port > 0) 151 if (m_HttpsPort > 0)
141 { 152 {
142 m_HttpsServer = MainServer.GetHttpServer(https_port); 153 m_HttpsServer = MainServer.GetHttpServer(m_HttpsPort);
143 } 154 }
144 } 155 }
145 156
@@ -172,12 +183,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
172 183
173 lock (m_UrlMap) 184 lock (m_UrlMap)
174 { 185 {
175 if (m_UrlMap.Count >= m_TotalUrls) 186 if (m_UrlMap.Count >= TotalUrls)
176 { 187 {
177 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 188 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
178 return urlcode; 189 return urlcode;
179 } 190 }
180 string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString(); 191 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString();
181 192
182 UrlData urlData = new UrlData(); 193 UrlData urlData = new UrlData();
183 urlData.hostID = host.UUID; 194 urlData.hostID = host.UUID;
@@ -218,12 +229,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
218 229
219 lock (m_UrlMap) 230 lock (m_UrlMap)
220 { 231 {
221 if (m_UrlMap.Count >= m_TotalUrls) 232 if (m_UrlMap.Count >= TotalUrls)
222 { 233 {
223 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 234 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
224 return urlcode; 235 return urlcode;
225 } 236 }
226 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString(); 237 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString();
227 238
228 UrlData urlData = new UrlData(); 239 UrlData urlData = new UrlData();
229 urlData.hostID = host.UUID; 240 urlData.hostID = host.UUID;
@@ -304,6 +315,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
304 UrlData urlData = m_RequestMap[request]; 315 UrlData urlData = m_RequestMap[request];
305 if (!urlData.requests[request].responseSent) 316 if (!urlData.requests[request].responseSent)
306 { 317 {
318 string responseBody = body;
319 if (urlData.requests[request].responseType.Equals("text/plain"))
320 {
321 string value;
322 if (urlData.requests[request].headers.TryGetValue("user-agent", out value))
323 {
324 if (value != null && value.IndexOf("MSIE") >= 0)
325 {
326 // wrap the html escaped response if the target client is IE
327 // It ignores "text/plain" if the body is html
328 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>";
329 }
330 }
331 }
332
307 urlData.requests[request].responseCode = status; 333 urlData.requests[request].responseCode = status;
308 urlData.requests[request].responseBody = body; 334 urlData.requests[request].responseBody = body;
309 //urlData.requests[request].ev.Set(); 335 //urlData.requests[request].ev.Set();
@@ -339,7 +365,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
339 365
340 public int GetFreeUrls() 366 public int GetFreeUrls()
341 { 367 {
342 return m_TotalUrls - m_UrlMap.Count; 368 lock (m_UrlMap)
369 return TotalUrls - m_UrlMap.Count;
343 } 370 }
344 371
345 public void ScriptRemoved(UUID itemID) 372 public void ScriptRemoved(UUID itemID)
@@ -533,7 +560,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
533 { 560 {
534 Hashtable headers = (Hashtable)request["headers"]; 561 Hashtable headers = (Hashtable)request["headers"];
535 562
536// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; 563// string uri_full = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
537 564
538 int pos1 = uri.IndexOf("/");// /lslhttp 565 int pos1 = uri.IndexOf("/");// /lslhttp
539 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/ 566 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
@@ -549,10 +576,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
549 UrlData url = null; 576 UrlData url = null;
550 string urlkey; 577 string urlkey;
551 if (!is_ssl) 578 if (!is_ssl)
552 urlkey = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 579 urlkey = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
553 //m_UrlMap[]; 580 //m_UrlMap[];
554 else 581 else
555 urlkey = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 582 urlkey = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
556 583
557 if (m_UrlMap.ContainsKey(urlkey)) 584 if (m_UrlMap.ContainsKey(urlkey))
558 { 585 {
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index f697c24..fccf053 100644
--- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -41,7 +41,7 @@ using System.Linq.Expressions;
41namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms 41namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
42{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
44 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms 44 public class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
45 { 45 {
46 private static readonly ILog m_log = 46 private static readonly ILog m_log =
47 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index f395441..2fc89fc 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -516,6 +516,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
516 foreach (string line in GetLines(data, dataDelim)) 516 foreach (string line in GetLines(data, dataDelim))
517 { 517 {
518 string nextLine = line.Trim(); 518 string nextLine = line.Trim();
519
520// m_log.DebugFormat("[VECTOR RENDER MODULE]: Processing line '{0}'", nextLine);
521
519 //replace with switch, or even better, do some proper parsing 522 //replace with switch, or even better, do some proper parsing
520 if (nextLine.StartsWith("MoveTo")) 523 if (nextLine.StartsWith("MoveTo"))
521 { 524 {
@@ -829,6 +832,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
829 float y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); 832 float y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture);
830 PointF point = new PointF(x, y); 833 PointF point = new PointF(x, y);
831 points[i / 2] = point; 834 points[i / 2] = point;
835
836// m_log.DebugFormat("[VECTOR RENDER MODULE]: Got point {0}", points[i / 2]);
832 } 837 }
833 } 838 }
834 } 839 }
@@ -838,13 +843,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
838 try 843 try
839 { 844 {
840 WebRequest request = HttpWebRequest.Create(url); 845 WebRequest request = HttpWebRequest.Create(url);
841//Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used. 846
842//Ckrinke Stream str = null; 847 using (HttpWebResponse response = (HttpWebResponse)(request).GetResponse())
843 HttpWebResponse response = (HttpWebResponse)(request).GetResponse();
844 if (response.StatusCode == HttpStatusCode.OK)
845 { 848 {
846 Bitmap image = new Bitmap(response.GetResponseStream()); 849 if (response.StatusCode == HttpStatusCode.OK)
847 return image; 850 {
851 using (Stream s = response.GetResponseStream())
852 {
853 Bitmap image = new Bitmap(s);
854 return image;
855 }
856 }
848 } 857 }
849 } 858 }
850 catch { } 859 catch { }
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
index 385f5ad..cbffca7 100644
--- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
@@ -111,13 +111,15 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
111 m_rpcPending = new Dictionary<UUID, RPCRequestInfo>(); 111 m_rpcPending = new Dictionary<UUID, RPCRequestInfo>();
112 m_rpcPendingResponses = new Dictionary<UUID, RPCRequestInfo>(); 112 m_rpcPendingResponses = new Dictionary<UUID, RPCRequestInfo>();
113 m_pendingSRDResponses = new Dictionary<UUID, SendRemoteDataRequest>(); 113 m_pendingSRDResponses = new Dictionary<UUID, SendRemoteDataRequest>();
114 114 if (config.Configs["XMLRPC"] != null)
115 try
116 {
117 m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort);
118 }
119 catch (Exception)
120 { 115 {
116 try
117 {
118 m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort);
119 }
120 catch (Exception)
121 {
122 }
121 } 123 }
122 } 124 }
123 125
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index 5836eb9..b61062f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -75,7 +75,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
75 public void Close() { } 75 public void Close() { }
76 public void PostInitialise() { } 76 public void PostInitialise() { }
77 77
78
79 ///<summary> 78 ///<summary>
80 /// 79 ///
81 ///</summary> 80 ///</summary>
@@ -136,7 +135,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
136 ///</summary> 135 ///</summary>
137 public void AddRegion(Scene scene) 136 public void AddRegion(Scene scene)
138 { 137 {
139 if (! m_enabled) 138 if (!m_enabled)
140 return; 139 return;
141 140
142 // Every shared region module has to maintain an indepedent list of 141 // Every shared region module has to maintain an indepedent list of
@@ -209,6 +208,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
209 208
210 using (Image mapTile = tileGenerator.CreateMapTile()) 209 using (Image mapTile = tileGenerator.CreateMapTile())
211 { 210 {
211 // XXX: The MapImageModule will return a null if the user has chosen not to create map tiles and there
212 // is no static map tile.
213 if (mapTile == null)
214 return;
215
212 using (MemoryStream stream = new MemoryStream()) 216 using (MemoryStream stream = new MemoryStream())
213 { 217 {
214 mapTile.Save(stream, ImageFormat.Jpeg); 218 mapTile.Save(stream, ImageFormat.Jpeg);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs
index 32e47f9..69bac82 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs
@@ -35,7 +35,6 @@ using NUnit.Framework;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using Nini.Config; 37using Nini.Config;
38
39using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence; 38using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence;
40using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; 40using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
@@ -44,11 +43,14 @@ using OpenSim.Tests.Common;
44namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests 43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests
45{ 44{
46 [TestFixture] 45 [TestFixture]
47 public class PresenceConnectorsTests 46 public class PresenceConnectorsTests : OpenSimTestCase
48 { 47 {
49 LocalPresenceServicesConnector m_LocalConnector; 48 LocalPresenceServicesConnector m_LocalConnector;
50 private void SetUp() 49
50 public override void SetUp()
51 { 51 {
52 base.SetUp();
53
52 IConfigSource config = new IniConfigSource(); 54 IConfigSource config = new IniConfigSource();
53 config.AddConfig("Modules"); 55 config.AddConfig("Modules");
54 config.AddConfig("PresenceService"); 56 config.AddConfig("PresenceService");
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index b485194..8b8bb37 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -219,12 +219,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
219 { 219 {
220// m_log.DebugFormat( 220// m_log.DebugFormat(
221// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", 221// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
222// s.RegionInfo.RegionName, destination.RegionHandle); 222// destination.RegionName, destination.RegionID);
223 223
224 return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); 224 return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData);
225 } 225 }
226 226
227// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); 227// m_log.DebugFormat(
228// "[LOCAL COMMS]: Did not find region {0} {1} for ChildAgentUpdate",
229// destination.RegionName, destination.RegionID);
230
228 return false; 231 return false;
229 } 232 }
230 233
@@ -239,7 +242,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
239 // note that we really don't need the GridRegion for this call 242 // note that we really don't need the GridRegion for this call
240 foreach (Scene s in m_scenes.Values) 243 foreach (Scene s in m_scenes.Values)
241 { 244 {
242 //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); 245// m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
243 s.IncomingChildAgentDataUpdate(cAgentData); 246 s.IncomingChildAgentDataUpdate(cAgentData);
244 } 247 }
245 248
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index ade5e76..fcfdf7c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -570,13 +570,22 @@ namespace OpenSim.Region.CoreModules.World.Archiver
570 570
571 // Validate User and Group UUID's 571 // Validate User and Group UUID's
572 572
573 if (!ResolveUserUuid(scene, parcel.OwnerID)) 573 if (parcel.IsGroupOwned)
574 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; 574 {
575 575 if (!ResolveGroupUuid(parcel.GroupID))
576 if (!ResolveGroupUuid(parcel.GroupID)) 576 {
577 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
578 parcel.GroupID = UUID.Zero;
579 parcel.IsGroupOwned = false;
580 }
581 }
582 else
577 { 583 {
578 parcel.GroupID = UUID.Zero; 584 if (!ResolveUserUuid(scene, parcel.OwnerID))
579 parcel.IsGroupOwned = false; 585 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
586
587 if (!ResolveGroupUuid(parcel.GroupID))
588 parcel.GroupID = UUID.Zero;
580 } 589 }
581 590
582 List<LandAccessEntry> accessList = new List<LandAccessEntry>(); 591 List<LandAccessEntry> accessList = new List<LandAccessEntry>();
@@ -589,8 +598,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
589 parcel.ParcelAccessList = accessList; 598 parcel.ParcelAccessList = accessList;
590 599
591// m_log.DebugFormat( 600// m_log.DebugFormat(
592// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}", 601// "[ARCHIVER]: Adding parcel {0}, local id {1}, owner {2}, group {3}, isGroupOwned {4}, area {5}",
593// parcel.Name, parcel.LocalID, parcel.Area); 602// parcel.Name, parcel.LocalID, parcel.OwnerID, parcel.GroupID, parcel.IsGroupOwned, parcel.Area);
594 603
595 landData.Add(parcel); 604 landData.Add(parcel);
596 } 605 }
@@ -613,13 +622,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
613 /// <returns></returns> 622 /// <returns></returns>
614 private bool ResolveUserUuid(Scene scene, UUID uuid) 623 private bool ResolveUserUuid(Scene scene, UUID uuid)
615 { 624 {
616 if (!m_validUserUuids.ContainsKey(uuid)) 625 lock (m_validUserUuids)
617 { 626 {
618 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid); 627 if (!m_validUserUuids.ContainsKey(uuid))
619 m_validUserUuids.Add(uuid, account != null); 628 {
620 } 629 // Note: we call GetUserAccount() inside the lock because this UserID is likely
630 // to occur many times, and we only want to query the users service once.
631 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid);
632 m_validUserUuids.Add(uuid, account != null);
633 }
621 634
622 return m_validUserUuids[uuid]; 635 return m_validUserUuids[uuid];
636 }
623 } 637 }
624 638
625 /// <summary> 639 /// <summary>
@@ -632,19 +646,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver
632 if (uuid == UUID.Zero) 646 if (uuid == UUID.Zero)
633 return true; // this means the object has no group 647 return true; // this means the object has no group
634 648
635 if (!m_validGroupUuids.ContainsKey(uuid)) 649 lock (m_validGroupUuids)
636 { 650 {
637 bool exists; 651 if (!m_validGroupUuids.ContainsKey(uuid))
638 652 {
639 if (m_groupsModule == null) 653 bool exists;
640 exists = false; 654 if (m_groupsModule == null)
641 else 655 {
642 exists = (m_groupsModule.GetGroupRecord(uuid) != null); 656 exists = false;
657 }
658 else
659 {
660 // Note: we call GetGroupRecord() inside the lock because this GroupID is likely
661 // to occur many times, and we only want to query the groups service once.
662 exists = (m_groupsModule.GetGroupRecord(uuid) != null);
663 }
664 m_validGroupUuids.Add(uuid, exists);
665 }
643 666
644 m_validGroupUuids.Add(uuid, exists); 667 return m_validGroupUuids[uuid];
645 } 668 }
646
647 return m_validGroupUuids[uuid];
648 } 669 }
649 670
650 /// Load an asset 671 /// Load an asset
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
index d751b1c..367693d 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -167,7 +167,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
167 } 167 }
168 scenesGroup.CalcSceneLocations(); 168 scenesGroup.CalcSceneLocations();
169 169
170
171 m_archiveWriter = new TarArchiveWriter(m_saveStream); 170 m_archiveWriter = new TarArchiveWriter(m_saveStream);
172 171
173 try 172 try
@@ -216,7 +215,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
216 } 215 }
217 } 216 }
218 217
219
220 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids) 218 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids)
221 { 219 {
222 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName); 220 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName);
@@ -540,7 +538,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
540 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); 538 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
541 } 539 }
542 540
543
544 protected void Save(Scene scene, List<SceneObjectGroup> sceneObjects, string regionDir) 541 protected void Save(Scene scene, List<SceneObjectGroup> sceneObjects, string regionDir)
545 { 542 {
546 if (regionDir != string.Empty) 543 if (regionDir != string.Empty)
@@ -560,8 +557,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
560 foreach (ILandObject lo in landObjects) 557 foreach (ILandObject lo in landObjects)
561 { 558 {
562 LandData landData = lo.LandData; 559 LandData landData = lo.LandData;
563 string landDataPath = String.Format("{0}{1}{2}.xml", 560 string landDataPath
564 regionDir, ArchiveConstants.LANDDATA_PATH, landData.GlobalID.ToString()); 561 = String.Format("{0}{1}", regionDir, ArchiveConstants.CreateOarLandDataPath(landData));
565 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options)); 562 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
566 } 563 }
567 564
@@ -590,21 +587,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
590 } 587 }
591 } 588 }
592 589
593 protected void ReceivedAllAssets( 590 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut)
594 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
595 { 591 {
596 foreach (UUID uuid in assetsNotFoundUuids) 592 string errorMessage;
593
594 if (timedOut)
597 { 595 {
598 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid); 596 errorMessage = "Loading assets timed out";
599 } 597 }
598 else
599 {
600 foreach (UUID uuid in assetsNotFoundUuids)
601 {
602 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid);
603 }
600 604
601 // m_log.InfoFormat( 605 // m_log.InfoFormat(
602 // "[ARCHIVER]: Received {0} of {1} assets requested", 606 // "[ARCHIVER]: Received {0} of {1} assets requested",
603 // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count); 607 // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
604 608
605 CloseArchive(String.Empty); 609 errorMessage = String.Empty;
610 }
611
612 CloseArchive(errorMessage);
606 } 613 }
607
608 614
609 /// <summary> 615 /// <summary>
610 /// Closes the archive and notifies that we're done. 616 /// Closes the archive and notifies that we're done.
@@ -629,6 +635,5 @@ namespace OpenSim.Region.CoreModules.World.Archiver
629 635
630 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage); 636 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage);
631 } 637 }
632
633 } 638 }
634} 639}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
index 95d109c..c1ff94d 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
@@ -150,12 +150,5 @@ namespace OpenSim.Region.CoreModules.World.Archiver
150 m_log.InfoFormat("[ARCHIVER]: Added {0} assets to archive", m_assetsWritten); 150 m_log.InfoFormat("[ARCHIVER]: Added {0} assets to archive", m_assetsWritten);
151 } 151 }
152 152
153 /// <summary>
154 /// Only call this if you need to force a close on the underlying writer.
155 /// </summary>
156 public void ForceClose()
157 {
158 m_archiveWriter.Close();
159 }
160 } 153 }
161} 154}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index e2f8833..ada7ecc 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
50 /// Method called when all the necessary assets for an archive request have been received. 50 /// Method called when all the necessary assets for an archive request have been received.
51 /// </summary> 51 /// </summary>
52 public delegate void AssetsRequestCallback( 52 public delegate void AssetsRequestCallback(
53 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids); 53 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut);
54 54
55 enum RequestState 55 enum RequestState
56 { 56 {
@@ -148,7 +148,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
148 if (m_repliesRequired == 0) 148 if (m_repliesRequired == 0)
149 { 149 {
150 m_requestState = RequestState.Completed; 150 m_requestState = RequestState.Completed;
151 PerformAssetsRequestCallback(null); 151 PerformAssetsRequestCallback(false);
152 return; 152 return;
153 } 153 }
154 154
@@ -156,6 +156,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
156 156
157 foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids) 157 foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids)
158 { 158 {
159// m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key);
160
159// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback); 161// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
160 AssetBase asset = m_assetService.Get(kvp.Key.ToString()); 162 AssetBase asset = m_assetService.Get(kvp.Key.ToString());
161 PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset); 163 PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset);
@@ -164,7 +166,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
164 166
165 protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args) 167 protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)
166 { 168 {
167 bool close = true; 169 bool timedOut = true;
168 170
169 try 171 try
170 { 172 {
@@ -174,7 +176,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
174 // the final request came in (assuming that such a thing is possible) 176 // the final request came in (assuming that such a thing is possible)
175 if (m_requestState == RequestState.Completed) 177 if (m_requestState == RequestState.Completed)
176 { 178 {
177 close = false; 179 timedOut = false;
178 return; 180 return;
179 } 181 }
180 182
@@ -223,8 +225,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
223 } 225 }
224 finally 226 finally
225 { 227 {
226 if (close) 228 if (timedOut)
227 m_assetsArchiver.ForceClose(); 229 Util.FireAndForget(PerformAssetsRequestCallback, true);
228 } 230 }
229 } 231 }
230 232
@@ -290,7 +292,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
290 292
291 // We want to stop using the asset cache thread asap 293 // We want to stop using the asset cache thread asap
292 // as we now need to do the work of producing the rest of the archive 294 // as we now need to do the work of producing the rest of the archive
293 Util.FireAndForget(PerformAssetsRequestCallback); 295 Util.FireAndForget(PerformAssetsRequestCallback, false);
294 } 296 }
295 else 297 else
296 { 298 {
@@ -311,9 +313,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
311 { 313 {
312 Culture.SetCurrentCulture(); 314 Culture.SetCurrentCulture();
313 315
316 Boolean timedOut = (Boolean)o;
317
314 try 318 try
315 { 319 {
316 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids); 320 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids, timedOut);
317 } 321 }
318 catch (Exception e) 322 catch (Exception e)
319 { 323 {
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 82f49b0..eec1cec 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -31,16 +31,19 @@ using System.IO;
31using System.Reflection; 31using System.Reflection;
32using System.Threading; 32using System.Threading;
33using log4net.Config; 33using log4net.Config;
34using Nini.Config;
34using NUnit.Framework; 35using NUnit.Framework;
35using OpenMetaverse; 36using OpenMetaverse;
36using OpenMetaverse.Assets; 37using OpenMetaverse.Assets;
37using OpenSim.Framework; 38using OpenSim.Framework;
38using OpenSim.Framework.Serialization; 39using OpenSim.Framework.Serialization;
39using OpenSim.Framework.Serialization.External; 40using OpenSim.Framework.Serialization.External;
41using OpenSim.Region.CoreModules.World.Land;
40using OpenSim.Region.CoreModules.World.Serialiser; 42using OpenSim.Region.CoreModules.World.Serialiser;
41using OpenSim.Region.CoreModules.World.Terrain; 43using OpenSim.Region.CoreModules.World.Terrain;
42using OpenSim.Region.Framework.Scenes; 44using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 45using OpenSim.Region.Framework.Scenes.Serialization;
46using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
44using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
45using OpenSim.Tests.Common.Mock; 48using OpenSim.Tests.Common.Mock;
46using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; 49using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants;
@@ -69,9 +72,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
69 { 72 {
70 base.SetUp(); 73 base.SetUp();
71 74
72 // FIXME: Do something about this - relying on statics in unit tests causes trouble sooner or later
73 new SceneManager();
74
75 m_archiverModule = new ArchiverModule(); 75 m_archiverModule = new ArchiverModule();
76 m_serialiserModule = new SerialiserModule(); 76 m_serialiserModule = new SerialiserModule();
77 TerrainModule terrainModule = new TerrainModule(); 77 TerrainModule terrainModule = new TerrainModule();
@@ -127,6 +127,53 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
127 127
128 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName }; 128 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
129 } 129 }
130
131 private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid)
132 {
133 SceneObjectPart part1 = CreateSceneObjectPart1();
134 sog1 = new SceneObjectGroup(part1);
135 scene.AddNewSceneObject(sog1, false);
136
137 AssetNotecard nc = new AssetNotecard();
138 nc.BodyText = "Hello World!";
139 nc.Encode();
140 ncAssetUuid = UUID.Random();
141 UUID ncItemUuid = UUID.Random();
142 AssetBase ncAsset
143 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
144 m_scene.AssetService.Store(ncAsset);
145
146 TaskInventoryItem ncItem
147 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
148 SceneObjectPart part2 = CreateSceneObjectPart2();
149 sog2 = new SceneObjectGroup(part2);
150 part2.Inventory.AddInventoryItem(ncItem, true);
151
152 scene.AddNewSceneObject(sog2, false);
153 }
154
155 private static void CreateSoundAsset(TarArchiveWriter tar, Assembly assembly, string soundDataResourceName, out byte[] soundData, out UUID soundUuid)
156 {
157 using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName))
158 {
159 using (BinaryReader br = new BinaryReader(resource))
160 {
161 // FIXME: Use the inspector instead
162 soundData = br.ReadBytes(99999999);
163 soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
164 string soundAssetFileName
165 = ArchiveConstants.ASSETS_PATH + soundUuid
166 + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
167 tar.WriteFile(soundAssetFileName, soundData);
168
169 /*
170 AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
171 scene.AssetService.Store(soundAsset);
172 asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
173 */
174 }
175 }
176 }
130 177
131 /// <summary> 178 /// <summary>
132 /// Test saving an OpenSim Region Archive. 179 /// Test saving an OpenSim Region Archive.
@@ -204,30 +251,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
204 // TODO: Test presence of more files and contents of files. 251 // TODO: Test presence of more files and contents of files.
205 } 252 }
206 253
207 private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid)
208 {
209 SceneObjectPart part1 = CreateSceneObjectPart1();
210 sog1 = new SceneObjectGroup(part1);
211 scene.AddNewSceneObject(sog1, false);
212
213 AssetNotecard nc = new AssetNotecard();
214 nc.BodyText = "Hello World!";
215 nc.Encode();
216 ncAssetUuid = UUID.Random();
217 UUID ncItemUuid = UUID.Random();
218 AssetBase ncAsset
219 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
220 m_scene.AssetService.Store(ncAsset);
221
222 TaskInventoryItem ncItem
223 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
224 SceneObjectPart part2 = CreateSceneObjectPart2();
225 sog2 = new SceneObjectGroup(part2);
226 part2.Inventory.AddInventoryItem(ncItem, true);
227
228 scene.AddNewSceneObject(sog2, false);
229 }
230
231 /// <summary> 254 /// <summary>
232 /// Test saving an OpenSim Region Archive with the no assets option 255 /// Test saving an OpenSim Region Archive with the no assets option
233 /// </summary> 256 /// </summary>
@@ -309,59 +332,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
309 } 332 }
310 333
311 /// <summary> 334 /// <summary>
312 /// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g.
313 /// 2 can come after 3).
314 /// </summary>
315 [Test]
316 public void TestLoadOarUnorderedParts()
317 {
318 TestHelpers.InMethod();
319
320 UUID ownerId = TestHelpers.ParseTail(0xaaaa);
321
322 MemoryStream archiveWriteStream = new MemoryStream();
323 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
324
325 tar.WriteFile(
326 ArchiveConstants.CONTROL_FILE_PATH,
327 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
328
329 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11);
330 SceneObjectPart sop2
331 = SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId);
332 SceneObjectPart sop3
333 = SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId);
334
335 // Add the parts so they will be written out in reverse order to the oar
336 sog1.AddPart(sop3);
337 sop3.LinkNum = 3;
338 sog1.AddPart(sop2);
339 sop2.LinkNum = 2;
340
341 tar.WriteFile(
342 ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition),
343 SceneObjectSerializer.ToXml2Format(sog1));
344
345 tar.Close();
346
347 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
348
349 lock (this)
350 {
351 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
352 m_archiverModule.DearchiveRegion(archiveReadStream);
353 }
354
355 Assert.That(m_lastErrorMessage, Is.Null);
356
357 SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2");
358 Assert.That(part2.LinkNum, Is.EqualTo(2));
359
360 SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3");
361 Assert.That(part3.LinkNum, Is.EqualTo(3));
362 }
363
364 /// <summary>
365 /// Test loading an OpenSim Region Archive. 335 /// Test loading an OpenSim Region Archive.
366 /// </summary> 336 /// </summary>
367 [Test] 337 [Test]
@@ -435,50 +405,57 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
435 TestLoadedRegion(part1, soundItemName, soundData); 405 TestLoadedRegion(part1, soundItemName, soundData);
436 } 406 }
437 407
438 private static void CreateSoundAsset(TarArchiveWriter tar, Assembly assembly, string soundDataResourceName, out byte[] soundData, out UUID soundUuid) 408 /// <summary>
409 /// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g.
410 /// 2 can come after 3).
411 /// </summary>
412 [Test]
413 public void TestLoadOarUnorderedParts()
439 { 414 {
440 using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName)) 415 TestHelpers.InMethod();
441 {
442 using (BinaryReader br = new BinaryReader(resource))
443 {
444 // FIXME: Use the inspector instead
445 soundData = br.ReadBytes(99999999);
446 soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
447 string soundAssetFileName
448 = ArchiveConstants.ASSETS_PATH + soundUuid
449 + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
450 tar.WriteFile(soundAssetFileName, soundData);
451 416
452 /* 417 UUID ownerId = TestHelpers.ParseTail(0xaaaa);
453 AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
454 scene.AssetService.Store(soundAsset);
455 asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
456 */
457 }
458 }
459 }
460 418
461 private void TestLoadedRegion(SceneObjectPart part1, string soundItemName, byte[] soundData) 419 MemoryStream archiveWriteStream = new MemoryStream();
462 { 420 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
463 SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
464 421
465 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); 422 tar.WriteFile(
466 Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical"); 423 ArchiveConstants.CONTROL_FILE_PATH,
467 Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal"); 424 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
468 Assert.That(
469 object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
470 Assert.That(
471 object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
472 Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation));
473 Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition));
474 425
475 TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; 426 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11);
476 Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); 427 SceneObjectPart sop2
477 AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString()); 428 = SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId);
478 Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null"); 429 SceneObjectPart sop3
479 Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); 430 = SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId);
480 431
481 Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels"); 432 // Add the parts so they will be written out in reverse order to the oar
433 sog1.AddPart(sop3);
434 sop3.LinkNum = 3;
435 sog1.AddPart(sop2);
436 sop2.LinkNum = 2;
437
438 tar.WriteFile(
439 ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition),
440 SceneObjectSerializer.ToXml2Format(sog1));
441
442 tar.Close();
443
444 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
445
446 lock (this)
447 {
448 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
449 m_archiverModule.DearchiveRegion(archiveReadStream);
450 }
451
452 Assert.That(m_lastErrorMessage, Is.Null);
453
454 SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2");
455 Assert.That(part2.LinkNum, Is.EqualTo(2));
456
457 SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3");
458 Assert.That(part3.LinkNum, Is.EqualTo(3));
482 } 459 }
483 460
484 /// <summary> 461 /// <summary>
@@ -538,8 +515,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
538 SerialiserModule serialiserModule = new SerialiserModule(); 515 SerialiserModule serialiserModule = new SerialiserModule();
539 TerrainModule terrainModule = new TerrainModule(); 516 TerrainModule terrainModule = new TerrainModule();
540 517
541 m_sceneHelpers = new SceneHelpers(); 518 SceneHelpers m_sceneHelpers2 = new SceneHelpers();
542 TestScene scene2 = m_sceneHelpers.SetupScene(); 519 TestScene scene2 = m_sceneHelpers2.SetupScene();
543 SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); 520 SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule);
544 521
545 // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is 522 // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is
@@ -563,6 +540,71 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
563 } 540 }
564 541
565 /// <summary> 542 /// <summary>
543 /// Test OAR loading where the land parcel is group deeded.
544 /// </summary>
545 /// <remarks>
546 /// In this situation, the owner ID is set to the group ID.
547 /// </remarks>
548 [Test]
549 public void TestLoadOarDeededLand()
550 {
551 TestHelpers.InMethod();
552// TestHelpers.EnableLogging();
553
554 UUID landID = TestHelpers.ParseTail(0x10);
555
556 MockGroupsServicesConnector groupsService = new MockGroupsServicesConnector();
557
558 IConfigSource configSource = new IniConfigSource();
559 IConfig config = configSource.AddConfig("Groups");
560 config.Set("Enabled", true);
561 config.Set("Module", "GroupsModule");
562 config.Set("DebugEnabled", true);
563 SceneHelpers.SetupSceneModules(
564 m_scene, configSource, new object[] { new GroupsModule(), groupsService, new LandManagementModule() });
565
566 // Create group in scene for loading
567 // FIXME: For now we'll put up with the issue that we'll get a group ID that varies across tests.
568 UUID groupID
569 = groupsService.CreateGroup(UUID.Zero, "group1", "", true, UUID.Zero, 3, true, true, true, UUID.Zero);
570
571 // Construct OAR
572 MemoryStream oarStream = new MemoryStream();
573 TarArchiveWriter tar = new TarArchiveWriter(oarStream);
574
575 tar.WriteDir(ArchiveConstants.LANDDATA_PATH);
576 tar.WriteFile(
577 ArchiveConstants.CONTROL_FILE_PATH,
578 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
579
580 LandObject lo = new LandObject(groupID, true, null);
581 lo.SetLandBitmap(lo.BasicFullRegionLandBitmap());
582 LandData ld = lo.LandData;
583 ld.GlobalID = landID;
584
585 string ldPath = ArchiveConstants.CreateOarLandDataPath(ld);
586 tar.WriteFile(ldPath, LandDataSerializer.Serialize(ld, null));
587 tar.Close();
588
589 oarStream = new MemoryStream(oarStream.ToArray());
590
591 // Load OAR
592 lock (this)
593 {
594 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
595 m_archiverModule.DearchiveRegion(oarStream);
596 }
597
598 ILandObject rLo = m_scene.LandChannel.GetLandObject(16, 16);
599 LandData rLd = rLo.LandData;
600
601 Assert.That(rLd.GlobalID, Is.EqualTo(landID));
602 Assert.That(rLd.OwnerID, Is.EqualTo(groupID));
603 Assert.That(rLd.GroupID, Is.EqualTo(groupID));
604 Assert.That(rLd.IsGroupOwned, Is.EqualTo(true));
605 }
606
607 /// <summary>
566 /// Test loading the region settings of an OpenSim Region Archive. 608 /// Test loading the region settings of an OpenSim Region Archive.
567 /// </summary> 609 /// </summary>
568 [Test] 610 [Test]
@@ -781,9 +823,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
781 } 823 }
782 } 824 }
783 825
784
785 // Save OAR 826 // Save OAR
786
787 MemoryStream archiveWriteStream = new MemoryStream(); 827 MemoryStream archiveWriteStream = new MemoryStream();
788 m_scene.EventManager.OnOarFileSaved += SaveCompleted; 828 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
789 829
@@ -800,7 +840,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
800 840
801 841
802 // Check that the OAR contains the expected data 842 // Check that the OAR contains the expected data
803
804 Assert.That(m_lastRequestId, Is.EqualTo(requestId)); 843 Assert.That(m_lastRequestId, Is.EqualTo(requestId));
805 844
806 byte[] archive = archiveWriteStream.ToArray(); 845 byte[] archive = archiveWriteStream.ToArray();
@@ -892,7 +931,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
892 } 931 }
893 932
894 ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup(); 933 ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup();
895 SceneManager.Instance.ForEachScene(delegate(Scene scene) 934 m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene)
896 { 935 {
897 scenesGroup.AddScene(scene); 936 scenesGroup.AddScene(scene);
898 }); 937 });
@@ -950,13 +989,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
950 989
951 // Delete the current objects, to test that they're loaded from the OAR and didn't 990 // Delete the current objects, to test that they're loaded from the OAR and didn't
952 // just remain in the scene. 991 // just remain in the scene.
953 SceneManager.Instance.ForEachScene(delegate(Scene scene) 992 m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene)
954 { 993 {
955 scene.DeleteAllSceneObjects(); 994 scene.DeleteAllSceneObjects();
956 }); 995 });
957 996
958 // Create a "hole", to test that that the corresponding region isn't loaded from the OAR 997 // Create a "hole", to test that that the corresponding region isn't loaded from the OAR
959 SceneManager.Instance.CloseScene(SceneManager.Instance.Scenes[1]); 998 m_sceneHelpers.SceneManager.CloseScene(SceneManager.Instance.Scenes[1]);
960 999
961 1000
962 // Check thay the OAR file contains the expected data 1001 // Check thay the OAR file contains the expected data
@@ -971,10 +1010,32 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
971 1010
972 Assert.That(m_lastErrorMessage, Is.Null); 1011 Assert.That(m_lastErrorMessage, Is.Null);
973 1012
974 Assert.AreEqual(3, SceneManager.Instance.Scenes.Count); 1013 Assert.AreEqual(3, m_sceneHelpers.SceneManager.Scenes.Count);
975 1014
976 TestLoadedRegion(part1, soundItemName, soundData); 1015 TestLoadedRegion(part1, soundItemName, soundData);
977 } 1016 }
978 1017
1018 private void TestLoadedRegion(SceneObjectPart part1, string soundItemName, byte[] soundData)
1019 {
1020 SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
1021
1022 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
1023 Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical");
1024 Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal");
1025 Assert.That(
1026 object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
1027 Assert.That(
1028 object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
1029 Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation));
1030 Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition));
1031
1032 TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
1033 Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
1034 AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
1035 Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null");
1036 Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
1037
1038 Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels");
1039 }
979 } 1040 }
980} 1041} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs
index 3b84d57..4d49794 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs
@@ -117,7 +117,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
117 117
118 m_module.Scene.RegionInfo.RegionSettings.Save(); 118 m_module.Scene.RegionInfo.RegionSettings.Save();
119 m_module.TriggerRegionInfoChange(); 119 m_module.TriggerRegionInfoChange();
120 m_module.sendRegionInfoPacketToAll(); 120 m_module.sendRegionHandshakeToAll();
121 } 121 }
122 } 122 }
123 } 123 }
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index dc062b6..a5f5749 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -55,6 +55,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
55 55
56 protected EstateManagementCommands m_commands; 56 protected EstateManagementCommands m_commands;
57 57
58 /// <summary>
59 /// If false, region restart requests from the client are blocked even if they are otherwise legitimate.
60 /// </summary>
61 public bool AllowRegionRestartFromClient { get; set; }
62
58 private EstateTerrainXferHandler TerrainUploader; 63 private EstateTerrainXferHandler TerrainUploader;
59 public TelehubManager m_Telehub; 64 public TelehubManager m_Telehub;
60 65
@@ -64,6 +69,53 @@ namespace OpenSim.Region.CoreModules.World.Estate
64 69
65 private int m_delayCount = 0; 70 private int m_delayCount = 0;
66 71
72 #region Region Module interface
73
74 public string Name { get { return "EstateManagementModule"; } }
75
76 public Type ReplaceableInterface { get { return null; } }
77
78 public void Initialise(IConfigSource source)
79 {
80 AllowRegionRestartFromClient = true;
81
82 IConfig config = source.Configs["EstateManagement"];
83
84 if (config != null)
85 AllowRegionRestartFromClient = config.GetBoolean("AllowRegionRestartFromClient", true);
86 }
87
88 public void AddRegion(Scene scene)
89 {
90 Scene = scene;
91 Scene.RegisterModuleInterface<IEstateModule>(this);
92 Scene.EventManager.OnNewClient += EventManager_OnNewClient;
93 Scene.EventManager.OnRequestChangeWaterHeight += changeWaterHeight;
94
95 m_Telehub = new TelehubManager(scene);
96
97 m_commands = new EstateManagementCommands(this);
98 m_commands.Initialise();
99 }
100
101 public void RemoveRegion(Scene scene) {}
102
103 public void RegionLoaded(Scene scene)
104 {
105 // Sets up the sun module based no the saved Estate and Region Settings
106 // DO NOT REMOVE or the sun will stop working
107 scene.TriggerEstateSunUpdate();
108
109 UserManager = scene.RequestModuleInterface<IUserManagement>();
110 }
111
112 public void Close()
113 {
114 m_commands.Close();
115 }
116
117 #endregion
118
67 #region Packet Data Responders 119 #region Packet Data Responders
68 120
69 private void clientSendDetailedEstateData(IClientAPI remote_client, UUID invoice) 121 private void clientSendDetailedEstateData(IClientAPI remote_client, UUID invoice)
@@ -76,7 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
76 { 128 {
77 uint sun = 0; 129 uint sun = 0;
78 130
79 if (!Scene.RegionInfo.EstateSettings.UseGlobalTime) 131 if (Scene.RegionInfo.EstateSettings.FixedSun)
80 sun = (uint)(Scene.RegionInfo.EstateSettings.SunPosition * 1024.0) + 0x1800; 132 sun = (uint)(Scene.RegionInfo.EstateSettings.SunPosition * 1024.0) + 0x1800;
81 UUID estateOwner; 133 UUID estateOwner;
82 estateOwner = Scene.RegionInfo.EstateSettings.EstateOwner; 134 estateOwner = Scene.RegionInfo.EstateSettings.EstateOwner;
@@ -197,6 +249,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
197 Scene.RegionInfo.RegionSettings.TerrainTexture4 = texture; 249 Scene.RegionInfo.RegionSettings.TerrainTexture4 = texture;
198 break; 250 break;
199 } 251 }
252
200 Scene.RegionInfo.RegionSettings.Save(); 253 Scene.RegionInfo.RegionSettings.Save();
201 TriggerRegionInfoChange(); 254 TriggerRegionInfoChange();
202 sendRegionInfoPacketToAll(); 255 sendRegionInfoPacketToAll();
@@ -228,6 +281,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
228 Scene.RegionInfo.RegionSettings.Elevation2NE = highValue; 281 Scene.RegionInfo.RegionSettings.Elevation2NE = highValue;
229 break; 282 break;
230 } 283 }
284
231 Scene.RegionInfo.RegionSettings.Save(); 285 Scene.RegionInfo.RegionSettings.Save();
232 TriggerRegionInfoChange(); 286 TriggerRegionInfoChange();
233 sendRegionHandshakeToAll(); 287 sendRegionHandshakeToAll();
@@ -268,6 +322,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
268 322
269 private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds) 323 private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds)
270 { 324 {
325 if (!AllowRegionRestartFromClient)
326 {
327 remoteClient.SendAlertMessage("Region restart has been disabled on this simulator.");
328 return;
329 }
330
271 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>(); 331 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>();
272 if (restartModule != null) 332 if (restartModule != null)
273 { 333 {
@@ -352,6 +412,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
352 } 412 }
353 413
354 } 414 }
415
355 if ((estateAccessType & 8) != 0) // User remove 416 if ((estateAccessType & 8) != 0) // User remove
356 { 417 {
357 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) 418 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
@@ -383,6 +444,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
383 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); 444 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
384 } 445 }
385 } 446 }
447
386 if ((estateAccessType & 16) != 0) // Group add 448 if ((estateAccessType & 16) != 0) // Group add
387 { 449 {
388 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) 450 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
@@ -650,7 +712,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
650 } 712 }
651 } 713 }
652 714
653 public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) 715 public void handleOnEstateManageTelehub(IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1)
654 { 716 {
655 SceneObjectPart part; 717 SceneObjectPart part;
656 718
@@ -718,13 +780,18 @@ namespace OpenSim.Region.CoreModules.World.Estate
718 Scene.RegionInfo.RegionSettings.Save(); 780 Scene.RegionInfo.RegionSettings.Save();
719 TriggerRegionInfoChange(); 781 TriggerRegionInfoChange();
720 782
721 Scene.SetSceneCoreDebug( 783 ISceneCommandsModule scm = Scene.RequestModuleInterface<ISceneCommandsModule>();
722 new Dictionary<string, string>() { 784
723 { "scripting", (!disableScripts).ToString() }, 785 if (scm != null)
724 { "collisions", (!disableCollisions).ToString() }, 786 {
725 { "physics", (!disablePhysics).ToString() } 787 scm.SetSceneDebugOptions(
726 } 788 new Dictionary<string, string>() {
727 ); 789 { "scripting", (!disableScripts).ToString() },
790 { "collisions", (!disableCollisions).ToString() },
791 { "physics", (!disablePhysics).ToString() }
792 }
793 );
794 }
728 } 795 }
729 796
730 private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey) 797 private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey)
@@ -1066,6 +1133,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
1066 { 1133 {
1067 Scene.RegionInfo.EstateSettings.UseGlobalTime = false; 1134 Scene.RegionInfo.EstateSettings.UseGlobalTime = false;
1068 Scene.RegionInfo.EstateSettings.SunPosition = (parms2 - 0x1800)/1024.0; 1135 Scene.RegionInfo.EstateSettings.SunPosition = (parms2 - 0x1800)/1024.0;
1136 // Warning: FixedSun should be set to True, otherwise this sun position won't be used.
1069 } 1137 }
1070 1138
1071 if ((parms1 & 0x00000010) != 0) 1139 if ((parms1 & 0x00000010) != 0)
@@ -1118,49 +1186,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
1118 1186
1119 #endregion 1187 #endregion
1120 1188
1121 #region Region Module interface
1122
1123 public string Name { get { return "EstateManagementModule"; } }
1124
1125 public Type ReplaceableInterface { get { return null; } }
1126
1127 public void Initialise(IConfigSource source) {}
1128
1129 public void AddRegion(Scene scene)
1130 {
1131 m_regionChangeTimer.AutoReset = false;
1132 m_regionChangeTimer.Interval = 2000;
1133 m_regionChangeTimer.Elapsed += RaiseRegionInfoChange;
1134
1135 Scene = scene;
1136 Scene.RegisterModuleInterface<IEstateModule>(this);
1137 Scene.EventManager.OnNewClient += EventManager_OnNewClient;
1138 Scene.EventManager.OnRequestChangeWaterHeight += changeWaterHeight;
1139
1140 m_Telehub = new TelehubManager(scene);
1141
1142 m_commands = new EstateManagementCommands(this);
1143 m_commands.Initialise();
1144 }
1145
1146 public void RemoveRegion(Scene scene) {}
1147
1148 public void RegionLoaded(Scene scene)
1149 {
1150 // Sets up the sun module based no the saved Estate and Region Settings
1151 // DO NOT REMOVE or the sun will stop working
1152 scene.TriggerEstateSunUpdate();
1153
1154 UserManager = scene.RequestModuleInterface<IUserManagement>();
1155 }
1156
1157 public void Close()
1158 {
1159 m_commands.Close();
1160 }
1161
1162 #endregion
1163
1164 #region Other Functions 1189 #region Other Functions
1165 1190
1166 public void changeWaterHeight(float height) 1191 public void changeWaterHeight(float height)
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
index 7fc358d..73c592d 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
@@ -95,6 +95,11 @@ namespace OpenSim.Region.CoreModules.World.Land
95 return null; 95 return null;
96 } 96 }
97 97
98 public ILandObject GetLandObject(Vector3 position)
99 {
100 return GetLandObject(position.X, position.Y);
101 }
102
98 public ILandObject GetLandObject(int x, int y) 103 public ILandObject GetLandObject(int x, int y)
99 { 104 {
100 if (m_landManagementModule != null) 105 if (m_landManagementModule != null)
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 1193057..b4f7d51 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -141,6 +141,7 @@ namespace OpenSim.Region.CoreModules.World.Land
141 m_scene.EventManager.OnValidateLandBuy += EventManagerOnValidateLandBuy; 141 m_scene.EventManager.OnValidateLandBuy += EventManagerOnValidateLandBuy;
142 m_scene.EventManager.OnLandBuy += EventManagerOnLandBuy; 142 m_scene.EventManager.OnLandBuy += EventManagerOnLandBuy;
143 m_scene.EventManager.OnNewClient += EventManagerOnNewClient; 143 m_scene.EventManager.OnNewClient += EventManagerOnNewClient;
144 m_scene.EventManager.OnMakeChildAgent += EventMakeChildAgent;
144 m_scene.EventManager.OnSignificantClientMovement += EventManagerOnSignificantClientMovement; 145 m_scene.EventManager.OnSignificantClientMovement += EventManagerOnSignificantClientMovement;
145 m_scene.EventManager.OnNoticeNoLandDataFromStorage += EventManagerOnNoLandDataFromStorage; 146 m_scene.EventManager.OnNoticeNoLandDataFromStorage += EventManagerOnNoLandDataFromStorage;
146 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; 147 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage;
@@ -221,6 +222,11 @@ namespace OpenSim.Region.CoreModules.World.Land
221 } 222 }
222 } 223 }
223 224
225 public void EventMakeChildAgent(ScenePresence avatar)
226 {
227 avatar.currentParcelUUID = UUID.Zero;
228 }
229
224 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 230 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
225 { 231 {
226 } 232 }
@@ -249,17 +255,15 @@ namespace OpenSim.Region.CoreModules.World.Land
249 newData.LocalID = local_id; 255 newData.LocalID = local_id;
250 ILandObject landobj = null; 256 ILandObject landobj = null;
251 257
258 ILandObject land;
252 lock (m_landList) 259 lock (m_landList)
253 { 260 {
254 if (m_landList.ContainsKey(local_id)) 261 if (m_landList.TryGetValue(local_id, out land))
255 { 262 land.LandData = newData;
256 m_landList[local_id].LandData = newData;
257 landobj = m_landList[local_id];
258// m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]);
259 }
260 } 263 }
261 if(landobj != null) 264
262 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landobj); 265 if (land != null)
266 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, land);
263 } 267 }
264 268
265 public bool AllowedForcefulBans 269 public bool AllowedForcefulBans
@@ -584,7 +588,7 @@ namespace OpenSim.Region.CoreModules.World.Land
584 // Only now can we add the prim counts to the land object - we rely on the global ID which is generated 588 // Only now can we add the prim counts to the land object - we rely on the global ID which is generated
585 // as a random UUID inside LandData initialization 589 // as a random UUID inside LandData initialization
586 if (m_primCountModule != null) 590 if (m_primCountModule != null)
587 new_land.PrimCounts = m_primCountModule.GetPrimCounts(new_land.LandData.GlobalID); 591 new_land.PrimCounts = m_primCountModule.GetPrimCounts(new_land.LandData.GlobalID);
588 592
589 lock (m_landList) 593 lock (m_landList)
590 { 594 {
@@ -621,6 +625,7 @@ namespace OpenSim.Region.CoreModules.World.Land
621 /// <param name="local_id">Land.localID of the peice of land to remove.</param> 625 /// <param name="local_id">Land.localID of the peice of land to remove.</param>
622 public void removeLandObject(int local_id) 626 public void removeLandObject(int local_id)
623 { 627 {
628 ILandObject land;
624 lock (m_landList) 629 lock (m_landList)
625 { 630 {
626 for (int x = 0; x < 64; x++) 631 for (int x = 0; x < 64; x++)
@@ -637,9 +642,11 @@ namespace OpenSim.Region.CoreModules.World.Land
637 } 642 }
638 } 643 }
639 644
640 m_scene.EventManager.TriggerLandObjectRemoved(m_landList[local_id].LandData.GlobalID); 645 land = m_landList[local_id];
641 m_landList.Remove(local_id); 646 m_landList.Remove(local_id);
642 } 647 }
648
649 m_scene.EventManager.TriggerLandObjectRemoved(land.LandData.GlobalID);
643 } 650 }
644 651
645 /// <summary> 652 /// <summary>
@@ -1384,9 +1391,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1384 } 1391 }
1385 1392
1386 for (int i = 0; i < data.Count; i++) 1393 for (int i = 0; i < data.Count; i++)
1387 {
1388 IncomingLandObjectFromStorage(data[i]); 1394 IncomingLandObjectFromStorage(data[i]);
1389 }
1390 } 1395 }
1391 1396
1392 public void IncomingLandObjectFromStorage(LandData data) 1397 public void IncomingLandObjectFromStorage(LandData data)
@@ -1401,25 +1406,72 @@ namespace OpenSim.Region.CoreModules.World.Land
1401 1406
1402 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1407 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
1403 { 1408 {
1404 ILandObject selectedParcel = null; 1409 if (localID != -1)
1405 lock (m_landList)
1406 { 1410 {
1407 m_landList.TryGetValue(localID, out selectedParcel); 1411 ILandObject selectedParcel = null;
1412 lock (m_landList)
1413 {
1414 m_landList.TryGetValue(localID, out selectedParcel);
1415 }
1416
1417 if (selectedParcel == null)
1418 return;
1419
1420 selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient);
1408 } 1421 }
1422 else
1423 {
1424 if (returnType != 1)
1425 {
1426 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: ReturnObjectsInParcel: unknown return type {0}", returnType);
1427 return;
1428 }
1429
1430 // We get here when the user returns objects from the list of Top Colliders or Top Scripts.
1431 // In that case we receive specific object UUID's, but no parcel ID.
1432
1433 Dictionary<UUID, HashSet<SceneObjectGroup>> returns = new Dictionary<UUID, HashSet<SceneObjectGroup>>();
1434
1435 foreach (UUID groupID in taskIDs)
1436 {
1437 SceneObjectGroup obj = m_scene.GetSceneObjectGroup(groupID);
1438 if (obj != null)
1439 {
1440 if (!returns.ContainsKey(obj.OwnerID))
1441 returns[obj.OwnerID] = new HashSet<SceneObjectGroup>();
1442 returns[obj.OwnerID].Add(obj);
1443 }
1444 else
1445 {
1446 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: ReturnObjectsInParcel: unknown object {0}", groupID);
1447 }
1448 }
1409 1449
1410 if (selectedParcel == null) return; 1450 int num = 0;
1451 foreach (HashSet<SceneObjectGroup> objs in returns.Values)
1452 num += objs.Count;
1453 m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Returning {0} specific object(s)", num);
1411 1454
1412 selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient); 1455 foreach (HashSet<SceneObjectGroup> objs in returns.Values)
1456 {
1457 List<SceneObjectGroup> objs2 = new List<SceneObjectGroup>(objs);
1458 if (m_scene.Permissions.CanReturnObjects(null, remoteClient.AgentId, objs2))
1459 {
1460 m_scene.returnObjects(objs2.ToArray(), remoteClient.AgentId);
1461 }
1462 else
1463 {
1464 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: ReturnObjectsInParcel: not permitted to return {0} object(s) belonging to user {1}",
1465 objs2.Count, objs2[0].OwnerID);
1466 }
1467 }
1468 }
1413 } 1469 }
1414 1470
1415 public void EventManagerOnNoLandDataFromStorage() 1471 public void EventManagerOnNoLandDataFromStorage()
1416 { 1472 {
1417 // called methods already have locks 1473 ResetSimLandObjects();
1418// lock (m_landList) 1474 CreateDefaultParcel();
1419 {
1420 ResetSimLandObjects();
1421 CreateDefaultParcel();
1422 }
1423 } 1475 }
1424 1476
1425 #endregion 1477 #endregion
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index fdac418..07d00c0 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -761,9 +761,10 @@ namespace OpenSim.Region.CoreModules.World.Land
761 int ty = min_y * 4; 761 int ty = min_y * 4;
762 if (ty > ((int)Constants.RegionSize - 1)) 762 if (ty > ((int)Constants.RegionSize - 1))
763 ty = ((int)Constants.RegionSize - 1); 763 ty = ((int)Constants.RegionSize - 1);
764
764 LandData.AABBMin = 765 LandData.AABBMin =
765 new Vector3((float) (min_x * 4), (float) (min_y * 4), 766 new Vector3(
766 (float) m_scene.Heightmap[tx, ty]); 767 (float)(min_x * 4), (float)(min_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
767 768
768 tx = max_x * 4; 769 tx = max_x * 4;
769 if (tx > ((int)Constants.RegionSize - 1)) 770 if (tx > ((int)Constants.RegionSize - 1))
@@ -771,9 +772,11 @@ namespace OpenSim.Region.CoreModules.World.Land
771 ty = max_y * 4; 772 ty = max_y * 4;
772 if (ty > ((int)Constants.RegionSize - 1)) 773 if (ty > ((int)Constants.RegionSize - 1))
773 ty = ((int)Constants.RegionSize - 1); 774 ty = ((int)Constants.RegionSize - 1);
774 LandData.AABBMax = 775
775 new Vector3((float) (max_x * 4), (float) (max_y * 4), 776 LandData.AABBMax
776 (float) m_scene.Heightmap[tx, ty]); 777 = new Vector3(
778 (float)(max_x * 4), (float)(max_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
779
777 LandData.Area = tempArea; 780 LandData.Area = tempArea;
778 } 781 }
779 782
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index 55b8227..771fdd2 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -490,11 +490,14 @@ namespace OpenSim.Region.CoreModules.World.Land
490 490
491 m_Scene.ForEachSOG(AddObject); 491 m_Scene.ForEachSOG(AddObject);
492 492
493 List<UUID> primcountKeys = new List<UUID>(m_PrimCounts.Keys); 493 lock (m_PrimCounts)
494 foreach (UUID k in primcountKeys)
495 { 494 {
496 if (!m_OwnerMap.ContainsKey(k)) 495 List<UUID> primcountKeys = new List<UUID>(m_PrimCounts.Keys);
497 m_PrimCounts.Remove(k); 496 foreach (UUID k in primcountKeys)
497 {
498 if (!m_OwnerMap.ContainsKey(k))
499 m_PrimCounts.Remove(k);
500 }
498 } 501 }
499 502
500 m_Tainted = false; 503 m_Tainted = false;
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
index b5ee4d2..0945b43 100644
--- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
+++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
@@ -41,7 +41,7 @@ using OpenSim.Tests.Common.Mock;
41namespace OpenSim.Region.CoreModules.World.Land.Tests 41namespace OpenSim.Region.CoreModules.World.Land.Tests
42{ 42{
43 [TestFixture] 43 [TestFixture]
44 public class PrimCountModuleTests 44 public class PrimCountModuleTests : OpenSimTestCase
45 { 45 {
46 protected UUID m_userId = new UUID("00000000-0000-0000-0000-100000000000"); 46 protected UUID m_userId = new UUID("00000000-0000-0000-0000-100000000000");
47 protected UUID m_groupId = new UUID("00000000-0000-0000-8888-000000000000"); 47 protected UUID m_groupId = new UUID("00000000-0000-0000-8888-000000000000");
@@ -60,8 +60,10 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
60 protected ILandObject m_lo2; 60 protected ILandObject m_lo2;
61 61
62 [SetUp] 62 [SetUp]
63 public void SetUp() 63 public override void SetUp()
64 { 64 {
65 base.SetUp();
66
65 m_pcm = new PrimCountModule(); 67 m_pcm = new PrimCountModule();
66 LandManagementModule lmm = new LandManagementModule(); 68 LandManagementModule lmm = new LandManagementModule();
67 m_scene = new SceneHelpers().SetupScene(); 69 m_scene = new SceneHelpers().SetupScene();
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
index 8a422b0..40638f8 100644
--- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
@@ -77,42 +77,48 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
77 { 77 {
78 bool drawPrimVolume = true; 78 bool drawPrimVolume = true;
79 bool textureTerrain = false; 79 bool textureTerrain = false;
80 bool generateMaptiles = true;
81 Bitmap mapbmp;
80 82
81 try 83 string[] configSections = new string[] { "Map", "Startup" };
82 {
83 IConfig startupConfig = m_config.Configs["Startup"];
84 drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", drawPrimVolume);
85 textureTerrain = startupConfig.GetBoolean("TextureOnMapTile", textureTerrain);
86 }
87 catch
88 {
89 m_log.Warn("[MAPTILE]: Failed to load StartupConfig");
90 }
91 84
92 if (textureTerrain) 85 drawPrimVolume
93 { 86 = Util.GetConfigVarFromSections<bool>(m_config, "DrawPrimOnMapTile", configSections, drawPrimVolume);
94 terrainRenderer = new TexturedMapTileRenderer(); 87 textureTerrain
95 } 88 = Util.GetConfigVarFromSections<bool>(m_config, "TextureOnMapTile", configSections, textureTerrain);
96 else 89 generateMaptiles
90 = Util.GetConfigVarFromSections<bool>(m_config, "GenerateMaptiles", configSections, generateMaptiles);
91
92 if (generateMaptiles)
97 { 93 {
98 terrainRenderer = new ShadedMapTileRenderer(); 94 if (textureTerrain)
99 } 95 {
100 terrainRenderer.Initialise(m_scene, m_config); 96 terrainRenderer = new TexturedMapTileRenderer();
97 }
98 else
99 {
100 terrainRenderer = new ShadedMapTileRenderer();
101 }
101 102
102 Bitmap mapbmp = new Bitmap((int)Constants.RegionSize, (int)Constants.RegionSize, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 103 terrainRenderer.Initialise(m_scene, m_config);
103 //long t = System.Environment.TickCount;
104 //for (int i = 0; i < 10; ++i) {
105 terrainRenderer.TerrainToBitmap(mapbmp);
106 //}
107 //t = System.Environment.TickCount - t;
108 //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t);
109 104
105 mapbmp = new Bitmap((int)Constants.RegionSize, (int)Constants.RegionSize, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
106 //long t = System.Environment.TickCount;
107 //for (int i = 0; i < 10; ++i) {
108 terrainRenderer.TerrainToBitmap(mapbmp);
109 //}
110 //t = System.Environment.TickCount - t;
111 //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t);
110 112
111 if (drawPrimVolume) 113 if (drawPrimVolume)
114 {
115 DrawObjectVolume(m_scene, mapbmp);
116 }
117 }
118 else
112 { 119 {
113 DrawObjectVolume(m_scene, mapbmp); 120 mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID);
114 } 121 }
115
116 return mapbmp; 122 return mapbmp;
117 } 123 }
118 124
@@ -139,9 +145,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
139 { 145 {
140 m_config = source; 146 m_config = source;
141 147
142 IConfig startupConfig = m_config.Configs["Startup"]; 148 if (Util.GetConfigVarFromSections<string>(
143 if (startupConfig.GetString("MapImageModule", "MapImageModule") != 149 m_config, "MapImageModule", new string[] { "Startup", "Map" }, "MapImageModule") != "MapImageModule")
144 "MapImageModule")
145 return; 150 return;
146 151
147 m_Enabled = true; 152 m_Enabled = true;
@@ -222,6 +227,49 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
222// } 227// }
223// } 228// }
224 229
230 private Bitmap FetchTexture(UUID id)
231 {
232 AssetBase asset = m_scene.AssetService.Get(id.ToString());
233
234 if (asset != null)
235 {
236 m_log.DebugFormat("[MAPTILE]: Static map image texture {0} found for {1}", id, m_scene.Name);
237 }
238 else
239 {
240 m_log.WarnFormat("[MAPTILE]: Static map image texture {0} not found for {1}", id, m_scene.Name);
241 return null;
242 }
243
244 ManagedImage managedImage;
245 Image image;
246
247 try
248 {
249 if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image))
250 return new Bitmap(image);
251 else
252 return null;
253 }
254 catch (DllNotFoundException)
255 {
256 m_log.ErrorFormat("[MAPTILE]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id);
257
258 }
259 catch (IndexOutOfRangeException)
260 {
261 m_log.ErrorFormat("[MAPTILE]: OpenJpeg was unable to decode this. Asset Data is empty for {0}", id);
262
263 }
264 catch (Exception)
265 {
266 m_log.ErrorFormat("[MAPTILE]: OpenJpeg was unable to decode this. Asset Data is empty for {0}", id);
267
268 }
269 return null;
270
271 }
272
225 private Bitmap DrawObjectVolume(Scene whichScene, Bitmap mapbmp) 273 private Bitmap DrawObjectVolume(Scene whichScene, Bitmap mapbmp)
226 { 274 {
227 int tc = 0; 275 int tc = 0;
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
index 396095a..03a96a4 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
@@ -44,14 +44,16 @@ using OpenSim.Tests.Common.Mock;
44namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests 44namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
45{ 45{
46 [TestFixture] 46 [TestFixture]
47 public class MoapTests 47 public class MoapTests : OpenSimTestCase
48 { 48 {
49 protected TestScene m_scene; 49 protected TestScene m_scene;
50 protected MoapModule m_module; 50 protected MoapModule m_module;
51 51
52 [SetUp] 52 [SetUp]
53 public void SetUp() 53 public override void SetUp()
54 { 54 {
55 base.SetUp();
56
55 m_module = new MoapModule(); 57 m_module = new MoapModule();
56 m_scene = new SceneHelpers().SetupScene(); 58 m_scene = new SceneHelpers().SetupScene();
57 SceneHelpers.SetupSceneModules(m_scene, m_module); 59 SceneHelpers.SetupSceneModules(m_scene, m_module);
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index ab8f143..28db407 100644
--- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
@@ -365,7 +365,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
365 365
366 if (mainParams.Count < 4) 366 if (mainParams.Count < 4)
367 { 367 {
368 m_console.OutputFormat("Usage: show part id [--full] <UUID-or-localID>"); 368 //m_console.OutputFormat("Usage: show part id [--full] <UUID-or-localID>");
369 m_console.OutputFormat("Usage: show part id <UUID-or-localID>");
369 return; 370 return;
370 } 371 }
371 372
@@ -405,6 +406,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
405 406
406 if (mainParams.Count < 5) 407 if (mainParams.Count < 5)
407 { 408 {
409 //m_console.OutputFormat("Usage: show part pos <start-coord> to <end-coord>");
408 m_console.OutputFormat("Usage: show part pos [--full] <start-coord> to <end-coord>"); 410 m_console.OutputFormat("Usage: show part pos [--full] <start-coord> to <end-coord>");
409 return; 411 return;
410 } 412 }
@@ -414,7 +416,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
414 416
415 if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) 417 if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
416 { 418 {
417 m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector); 419 m_console.OutputFormat("Error: Start vector '{0}' does not have a valid format", rawConsoleStartVector);
418 return; 420 return;
419 } 421 }
420 422
@@ -423,7 +425,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
423 425
424 if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) 426 if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
425 { 427 {
426 m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector); 428 m_console.OutputFormat("Error: End vector '{0}' does not have a valid format", rawConsoleEndVector);
427 return; 429 return;
428 } 430 }
429 431
@@ -445,7 +447,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
445 447
446 if (mainParams.Count < 4) 448 if (mainParams.Count < 4)
447 { 449 {
448 m_console.OutputFormat("Usage: show part name [--full] [--regex] <name>"); 450 m_console.OutputFormat("Usage: show part name [--regex] <name>");
451 //m_console.OutputFormat("Usage: show part name [--full] [--regex] <name>");
449 return; 452 return;
450 } 453 }
451 454
@@ -577,6 +580,58 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
577 cdl.AddRow("Link number", sop.LinkNum); 580 cdl.AddRow("Link number", sop.LinkNum);
578 cdl.AddRow("Flags", sop.Flags); 581 cdl.AddRow("Flags", sop.Flags);
579 582
583 if (showFull)
584 {
585 PrimitiveBaseShape s = sop.Shape;
586 cdl.AddRow("FlexiDrag", s.FlexiDrag);
587 cdl.AddRow("FlexiEntry", s.FlexiEntry);
588 cdl.AddRow("FlexiForce", string.Format("<{0},{1},{2}>", s.FlexiForceX, s.FlexiForceY, s.FlexiForceZ));
589 cdl.AddRow("FlexiGravity", s.FlexiGravity);
590 cdl.AddRow("FlexiSoftness", s.FlexiSoftness);
591 cdl.AddRow("HollowShape", s.HollowShape);
592 cdl.AddRow(
593 "LightColor",
594 string.Format("<{0},{1},{2},{3}>", s.LightColorR, s.LightColorB, s.LightColorG, s.LightColorA));
595 cdl.AddRow("LightCutoff", s.LightCutoff);
596 cdl.AddRow("LightEntry", s.LightEntry);
597 cdl.AddRow("LightFalloff", s.LightFalloff);
598 cdl.AddRow("LightIntensity", s.LightIntensity);
599 cdl.AddRow("LightRadius", s.LightRadius);
600 cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a"));
601 cdl.AddRow("PathBegin", s.PathBegin);
602 cdl.AddRow("PathEnd", s.PathEnd);
603 cdl.AddRow("PathCurve", s.PathCurve);
604 cdl.AddRow("PathRadiusOffset", s.PathRadiusOffset);
605 cdl.AddRow("PathRevolutions", s.PathRevolutions);
606 cdl.AddRow("PathScale", string.Format("<{0},{1}>", s.PathScaleX, s.PathScaleY));
607 cdl.AddRow("PathSkew", string.Format("<{0},{1}>", s.PathShearX, s.PathShearY));
608 cdl.AddRow("FlexiDrag", s.PathSkew);
609 cdl.AddRow("PathTaper", string.Format("<{0},{1}>", s.PathTaperX, s.PathTaperY));
610 cdl.AddRow("PathTwist", s.PathTwist);
611 cdl.AddRow("PathTwistBegin", s.PathTwistBegin);
612 cdl.AddRow("PCode", s.PCode);
613 cdl.AddRow("ProfileBegin", s.ProfileBegin);
614 cdl.AddRow("ProfileEnd", s.ProfileEnd);
615 cdl.AddRow("ProfileHollow", s.ProfileHollow);
616 cdl.AddRow("ProfileShape", s.ProfileShape);
617 cdl.AddRow("ProjectionAmbiance", s.ProjectionAmbiance);
618 cdl.AddRow("ProjectionEntry", s.ProjectionEntry);
619 cdl.AddRow("ProjectionFocus", s.ProjectionFocus);
620 cdl.AddRow("ProjectionFOV", s.ProjectionFOV);
621 cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID);
622 cdl.AddRow("Scale", s.Scale);
623 cdl.AddRow(
624 "SculptData",
625 string.Format("{0} bytes", s.SculptData != null ? s.SculptData.Length.ToString() : "n/a"));
626 cdl.AddRow("SculptEntry", s.SculptEntry);
627 cdl.AddRow("SculptTexture", s.SculptTexture);
628 cdl.AddRow("SculptType", s.SculptType);
629 cdl.AddRow("State", s.State);
630
631 // TODO, unpack and display texture entries
632 //cdl.AddRow("Textures", string.Format("{0} entries", s.Textures.
633 }
634
580 object itemsOutput; 635 object itemsOutput;
581 if (showFull) 636 if (showFull)
582 { 637 {
@@ -588,7 +643,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
588 itemsOutput = sop.Inventory.Count; 643 itemsOutput = sop.Inventory.Count;
589 } 644 }
590 645
591
592 cdl.AddRow("Items", itemsOutput); 646 cdl.AddRow("Items", itemsOutput);
593 647
594 return sb.Append(cdl.ToString()); 648 return sb.Append(cdl.ToString());
@@ -842,17 +896,17 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
842 896
843 if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) 897 if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
844 { 898 {
845 m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector); 899 m_console.OutputFormat("Error: Start vector '{0}' does not have a valid format", rawConsoleStartVector);
846 endVector = Vector3.Zero; 900 endVector = Vector3.Zero;
847 901
848 return false; 902 return false;
849 } 903 }
850 904
851 string rawConsoleEndVector = rawComponents.Skip(1).Take(1).Single(); 905 string rawConsoleEndVector = rawComponents.Skip(2).Take(1).Single();
852 906
853 if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) 907 if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
854 { 908 {
855 m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector); 909 m_console.OutputFormat("Error: End vector '{0}' does not have a valid format", rawConsoleEndVector);
856 return false; 910 return false;
857 } 911 }
858 912
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index ddaa227..121fb2a 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -156,9 +156,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
156 156
157 public void Initialise(IConfigSource config) 157 public void Initialise(IConfigSource config)
158 { 158 {
159 IConfig myConfig = config.Configs["Startup"]; 159 string permissionModules = Util.GetConfigVarFromSections<string>(config, "permissionmodules",
160 160 new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule");
161 string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule");
162 161
163 List<string> modules = new List<string>(permissionModules.Split(',')); 162 List<string> modules = new List<string>(permissionModules.Split(','));
164 163
@@ -167,26 +166,34 @@ namespace OpenSim.Region.CoreModules.World.Permissions
167 166
168 m_Enabled = true; 167 m_Enabled = true;
169 168
170 m_allowGridGods = myConfig.GetBoolean("allow_grid_gods", false); 169 m_allowGridGods = Util.GetConfigVarFromSections<bool>(config, "allow_grid_gods",
171 m_bypassPermissions = !myConfig.GetBoolean("serverside_object_permissions", true); 170 new string[] { "Startup", "Permissions" }, false);
172 m_propagatePermissions = myConfig.GetBoolean("propagate_permissions", true); 171 m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(config, "serverside_object_permissions",
173 m_RegionOwnerIsGod = myConfig.GetBoolean("region_owner_is_god", true); 172 new string[] { "Startup", "Permissions" }, true);
174 m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false); 173 m_propagatePermissions = Util.GetConfigVarFromSections<bool>(config, "propagate_permissions",
175 m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true); 174 new string[] { "Startup", "Permissions" }, true);
176 175 m_RegionOwnerIsGod = Util.GetConfigVarFromSections<bool>(config, "region_owner_is_god",
177 m_SimpleBuildPermissions = myConfig.GetBoolean("simple_build_permissions", false); 176 new string[] { "Startup", "Permissions" }, true);
177 m_RegionManagerIsGod = Util.GetConfigVarFromSections<bool>(config, "region_manager_is_god",
178 new string[] { "Startup", "Permissions" }, false);
179 m_ParcelOwnerIsGod = Util.GetConfigVarFromSections<bool>(config, "parcel_owner_is_god",
180 new string[] { "Startup", "Permissions" }, true);
181
182 m_SimpleBuildPermissions = Util.GetConfigVarFromSections<bool>(config, "simple_build_permissions",
183 new string[] { "Startup", "Permissions" }, false);
178 184
179 m_allowedScriptCreators 185 m_allowedScriptCreators
180 = ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators); 186 = ParseUserSetConfigSetting(config, "allowed_script_creators", m_allowedScriptCreators);
181 m_allowedScriptEditors 187 m_allowedScriptEditors
182 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors); 188 = ParseUserSetConfigSetting(config, "allowed_script_editors", m_allowedScriptEditors);
183 189
184 if (m_bypassPermissions) 190 if (m_bypassPermissions)
185 m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks"); 191 m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks");
186 else 192 else
187 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); 193 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
188 194
189 string grant = myConfig.GetString("GrantLSL", ""); 195 string grant = Util.GetConfigVarFromSections<string>(config, "GrantLSL",
196 new string[] { "Startup", "Permissions" }, string.Empty);
190 if (grant.Length > 0) 197 if (grant.Length > 0)
191 { 198 {
192 foreach (string uuidl in grant.Split(',')) 199 foreach (string uuidl in grant.Split(','))
@@ -196,7 +203,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
196 } 203 }
197 } 204 }
198 205
199 grant = myConfig.GetString("GrantCS", ""); 206 grant = Util.GetConfigVarFromSections<string>(config, "GrantCS",
207 new string[] { "Startup", "Permissions" }, string.Empty);
200 if (grant.Length > 0) 208 if (grant.Length > 0)
201 { 209 {
202 foreach (string uuidl in grant.Split(',')) 210 foreach (string uuidl in grant.Split(','))
@@ -206,7 +214,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
206 } 214 }
207 } 215 }
208 216
209 grant = myConfig.GetString("GrantVB", ""); 217 grant = Util.GetConfigVarFromSections<string>(config, "GrantVB",
218 new string[] { "Startup", "Permissions" }, string.Empty);
210 if (grant.Length > 0) 219 if (grant.Length > 0)
211 { 220 {
212 foreach (string uuidl in grant.Split(',')) 221 foreach (string uuidl in grant.Split(','))
@@ -216,7 +225,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
216 } 225 }
217 } 226 }
218 227
219 grant = myConfig.GetString("GrantJS", ""); 228 grant = Util.GetConfigVarFromSections<string>(config, "GrantJS",
229 new string[] { "Startup", "Permissions" }, string.Empty);
220 if (grant.Length > 0) 230 if (grant.Length > 0)
221 { 231 {
222 foreach (string uuidl in grant.Split(',')) 232 foreach (string uuidl in grant.Split(','))
@@ -226,7 +236,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
226 } 236 }
227 } 237 }
228 238
229 grant = myConfig.GetString("GrantYP", ""); 239 grant = Util.GetConfigVarFromSections<string>(config, "GrantYP",
240 new string[] { "Startup", "Permissions" }, string.Empty);
230 if (grant.Length > 0) 241 if (grant.Length > 0)
231 { 242 {
232 foreach (string uuidl in grant.Split(',')) 243 foreach (string uuidl in grant.Split(','))
@@ -464,11 +475,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
464 /// <param name="settingName"></param> 475 /// <param name="settingName"></param>
465 /// <param name="defaultValue">The default value for this attribute</param> 476 /// <param name="defaultValue">The default value for this attribute</param>
466 /// <returns>The parsed value</returns> 477 /// <returns>The parsed value</returns>
467 private static UserSet ParseUserSetConfigSetting(IConfig config, string settingName, UserSet defaultValue) 478 private static UserSet ParseUserSetConfigSetting(IConfigSource config, string settingName, UserSet defaultValue)
468 { 479 {
469 UserSet userSet = defaultValue; 480 UserSet userSet = defaultValue;
470 481
471 string rawSetting = config.GetString(settingName, defaultValue.ToString()); 482 string rawSetting = Util.GetConfigVarFromSections<string>(config, settingName,
483 new string[] {"Startup", "Permissions"}, defaultValue.ToString());
472 484
473 // Temporary measure to allow 'gods' to be specified in config for consistency's sake. In the long term 485 // Temporary measure to allow 'gods' to be specified in config for consistency's sake. In the long term
474 // this should disappear. 486 // this should disappear.
diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
index 7825e3e..b4348c9 100644
--- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
+++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
@@ -35,11 +35,12 @@ using OpenSim.Framework;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Region.Framework.Scenes.Serialization; 36using OpenSim.Region.Framework.Scenes.Serialization;
37using OpenSim.Tests.Common; 37using OpenSim.Tests.Common;
38using OpenMetaverse.StructuredData;
38 39
39namespace OpenSim.Region.CoreModules.World.Serialiser.Tests 40namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
40{ 41{
41 [TestFixture] 42 [TestFixture]
42 public class SerialiserTests 43 public class SerialiserTests : OpenSimTestCase
43 { 44 {
44 private string xml = @" 45 private string xml = @"
45 <SceneObjectGroup> 46 <SceneObjectGroup>
@@ -143,6 +144,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
143 <Flags>None</Flags> 144 <Flags>None</Flags>
144 <CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound> 145 <CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound>
145 <CollisionSoundVolume>0</CollisionSoundVolume> 146 <CollisionSoundVolume>0</CollisionSoundVolume>
147 <DynAttrs><llsd><map><key>MyStore</key><map><key>the answer</key><integer>42</integer></map></map></llsd></DynAttrs>
146 </SceneObjectPart> 148 </SceneObjectPart>
147 </RootPart> 149 </RootPart>
148 <OtherParts /> 150 <OtherParts />
@@ -331,6 +333,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
331 <EveryoneMask>0</EveryoneMask> 333 <EveryoneMask>0</EveryoneMask>
332 <NextOwnerMask>2147483647</NextOwnerMask> 334 <NextOwnerMask>2147483647</NextOwnerMask>
333 <Flags>None</Flags> 335 <Flags>None</Flags>
336 <DynAttrs><llsd><map><key>MyStore</key><map><key>last words</key><string>Rosebud</string></map></map></llsd></DynAttrs>
334 <SitTargetAvatar><UUID>00000000-0000-0000-0000-000000000000</UUID></SitTargetAvatar> 337 <SitTargetAvatar><UUID>00000000-0000-0000-0000-000000000000</UUID></SitTargetAvatar>
335 </SceneObjectPart> 338 </SceneObjectPart>
336 <OtherParts /> 339 <OtherParts />
@@ -359,6 +362,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
359 Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790"))); 362 Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790")));
360 Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d"))); 363 Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d")));
361 Assert.That(rootPart.Name, Is.EqualTo("PrimMyRide")); 364 Assert.That(rootPart.Name, Is.EqualTo("PrimMyRide"));
365 OSDMap store = rootPart.DynAttrs["MyStore"];
366 Assert.AreEqual(42, store["the answer"].AsInteger());
362 367
363 // TODO: Check other properties 368 // TODO: Check other properties
364 } 369 }
@@ -409,6 +414,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
409 rp.CreatorID = rpCreatorId; 414 rp.CreatorID = rpCreatorId;
410 rp.Shape = shape; 415 rp.Shape = shape;
411 416
417 string daStoreName = "MyStore";
418 string daKey = "foo";
419 string daValue = "bar";
420 OSDMap myStore = new OSDMap();
421 myStore.Add(daKey, daValue);
422 rp.DynAttrs = new DAMap();
423 rp.DynAttrs[daStoreName] = myStore;
424
412 SceneObjectGroup so = new SceneObjectGroup(rp); 425 SceneObjectGroup so = new SceneObjectGroup(rp);
413 426
414 // Need to add the object to the scene so that the request to get script state succeeds 427 // Need to add the object to the scene so that the request to get script state succeeds
@@ -424,6 +437,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
424 UUID uuid = UUID.Zero; 437 UUID uuid = UUID.Zero;
425 string name = null; 438 string name = null;
426 UUID creatorId = UUID.Zero; 439 UUID creatorId = UUID.Zero;
440 DAMap daMap = null;
427 441
428 while (xtr.Read() && xtr.Name != "SceneObjectPart") 442 while (xtr.Read() && xtr.Name != "SceneObjectPart")
429 { 443 {
@@ -449,6 +463,10 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
449 creatorId = UUID.Parse(xtr.ReadElementString("UUID")); 463 creatorId = UUID.Parse(xtr.ReadElementString("UUID"));
450 xtr.ReadEndElement(); 464 xtr.ReadEndElement();
451 break; 465 break;
466 case "DynAttrs":
467 daMap = new DAMap();
468 daMap.ReadXml(xtr);
469 break;
452 } 470 }
453 } 471 }
454 472
@@ -462,6 +480,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
462 Assert.That(uuid, Is.EqualTo(rpUuid)); 480 Assert.That(uuid, Is.EqualTo(rpUuid));
463 Assert.That(name, Is.EqualTo(rpName)); 481 Assert.That(name, Is.EqualTo(rpName));
464 Assert.That(creatorId, Is.EqualTo(rpCreatorId)); 482 Assert.That(creatorId, Is.EqualTo(rpCreatorId));
483 Assert.NotNull(daMap);
484 Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString());
465 } 485 }
466 486
467 [Test] 487 [Test]
@@ -476,6 +496,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
476 Assert.That(rootPart.UUID, Is.EqualTo(new UUID("9be68fdd-f740-4a0f-9675-dfbbb536b946"))); 496 Assert.That(rootPart.UUID, Is.EqualTo(new UUID("9be68fdd-f740-4a0f-9675-dfbbb536b946")));
477 Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("b46ef588-411e-4a8b-a284-d7dcfe8e74ef"))); 497 Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("b46ef588-411e-4a8b-a284-d7dcfe8e74ef")));
478 Assert.That(rootPart.Name, Is.EqualTo("PrimFun")); 498 Assert.That(rootPart.Name, Is.EqualTo("PrimFun"));
499 OSDMap store = rootPart.DynAttrs["MyStore"];
500 Assert.AreEqual("Rosebud", store["last words"].AsString());
479 501
480 // TODO: Check other properties 502 // TODO: Check other properties
481 } 503 }
@@ -500,6 +522,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
500 rp.CreatorID = rpCreatorId; 522 rp.CreatorID = rpCreatorId;
501 rp.Shape = shape; 523 rp.Shape = shape;
502 524
525 string daStoreName = "MyStore";
526 string daKey = "foo";
527 string daValue = "bar";
528 OSDMap myStore = new OSDMap();
529 myStore.Add(daKey, daValue);
530 rp.DynAttrs = new DAMap();
531 rp.DynAttrs[daStoreName] = myStore;
532
503 SceneObjectGroup so = new SceneObjectGroup(rp); 533 SceneObjectGroup so = new SceneObjectGroup(rp);
504 534
505 // Need to add the object to the scene so that the request to get script state succeeds 535 // Need to add the object to the scene so that the request to get script state succeeds
@@ -516,6 +546,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
516 UUID uuid = UUID.Zero; 546 UUID uuid = UUID.Zero;
517 string name = null; 547 string name = null;
518 UUID creatorId = UUID.Zero; 548 UUID creatorId = UUID.Zero;
549 DAMap daMap = null;
519 550
520 while (xtr.Read() && xtr.Name != "SceneObjectPart") 551 while (xtr.Read() && xtr.Name != "SceneObjectPart")
521 { 552 {
@@ -537,6 +568,10 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
537 creatorId = UUID.Parse(xtr.ReadElementString("Guid")); 568 creatorId = UUID.Parse(xtr.ReadElementString("Guid"));
538 xtr.ReadEndElement(); 569 xtr.ReadEndElement();
539 break; 570 break;
571 case "DynAttrs":
572 daMap = new DAMap();
573 daMap.ReadXml(xtr);
574 break;
540 } 575 }
541 } 576 }
542 577
@@ -549,6 +584,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
549 Assert.That(uuid, Is.EqualTo(rpUuid)); 584 Assert.That(uuid, Is.EqualTo(rpUuid));
550 Assert.That(name, Is.EqualTo(rpName)); 585 Assert.That(name, Is.EqualTo(rpName));
551 Assert.That(creatorId, Is.EqualTo(rpCreatorId)); 586 Assert.That(creatorId, Is.EqualTo(rpCreatorId));
587 Assert.NotNull(daMap);
588 Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString());
552 } 589 }
553 } 590 }
554} \ No newline at end of file 591} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index 513a8f5..883045a 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -43,8 +43,8 @@ namespace OpenSim.Region.CoreModules.World.Sound
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SoundModule")] 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SoundModule")]
44 public class SoundModule : INonSharedRegionModule, ISoundModule 44 public class SoundModule : INonSharedRegionModule, ISoundModule
45 { 45 {
46 private static readonly ILog m_log = LogManager.GetLogger( 46// private static readonly ILog m_log = LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType); 47// MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 private Scene m_scene; 49 private Scene m_scene;
50 50
@@ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
76 76
77 public void RemoveRegion(Scene scene) 77 public void RemoveRegion(Scene scene)
78 { 78 {
79 m_scene.EventManager.OnClientLogin -= OnNewClient; 79 m_scene.EventManager.OnNewClient -= OnNewClient;
80 } 80 }
81 81
82 public void RegionLoaded(Scene scene) 82 public void RegionLoaded(Scene scene)
@@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
85 return; 85 return;
86 86
87 m_scene = scene; 87 m_scene = scene;
88 m_scene.EventManager.OnClientLogin += OnNewClient; 88 m_scene.EventManager.OnNewClient += OnNewClient;
89 89
90 m_scene.RegisterModuleInterface<ISoundModule>(this); 90 m_scene.RegisterModuleInterface<ISoundModule>(this);
91 } 91 }
diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
index a321c09..6f344c8 100644
--- a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
@@ -252,12 +252,11 @@ namespace OpenSim.Region.CoreModules
252 } 252 }
253 253
254 // TODO: Decouple this, so we can get rid of Linden Hour info 254 // TODO: Decouple this, so we can get rid of Linden Hour info
255 // Update Region infor with new Sun Position and Hour 255 // Update Region with new Sun Vector
256 // set estate settings for region access to sun position 256 // set estate settings for region access to sun position
257 if (receivedEstateToolsSunUpdate) 257 if (receivedEstateToolsSunUpdate)
258 { 258 {
259 m_scene.RegionInfo.RegionSettings.SunVector = Position; 259 m_scene.RegionInfo.RegionSettings.SunVector = Position;
260 m_scene.RegionInfo.RegionSettings.SunPosition = GetCurrentTimeAsLindenSunHour();
261 } 260 }
262 } 261 }
263 262
@@ -395,7 +394,7 @@ namespace OpenSim.Region.CoreModules
395 ready = false; 394 ready = false;
396 395
397 // Remove our hooks 396 // Remove our hooks
398 m_scene.EventManager.OnFrame -= SunUpdate; 397 m_scene.EventManager.OnFrame -= SunUpdate;
399 m_scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; 398 m_scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel;
400 m_scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate; 399 m_scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate;
401 m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour; 400 m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour;
@@ -459,26 +458,33 @@ namespace OpenSim.Region.CoreModules
459 SunToClient(avatar.ControllingClient); 458 SunToClient(avatar.ControllingClient);
460 } 459 }
461 460
462 /// <summary> 461 public void EstateToolsSunUpdate(ulong regionHandle)
463 ///
464 /// </summary>
465 /// <param name="regionHandle"></param>
466 /// <param name="FixedTime">Is the sun's position fixed?</param>
467 /// <param name="useEstateTime">Use the Region or Estate Sun hour?</param>
468 /// <param name="FixedSunHour">What hour of the day is the Sun Fixed at?</param>
469 public void EstateToolsSunUpdate(ulong regionHandle, bool FixedSun, bool useEstateTime, float FixedSunHour)
470 { 462 {
471 if (m_scene.RegionInfo.RegionHandle == regionHandle) 463 if (m_scene.RegionInfo.RegionHandle == regionHandle)
472 { 464 {
473 // Must limit the Sun Hour to 0 ... 24 465 float sunFixedHour;
474 while (FixedSunHour > 24.0f) 466 bool fixedSun;
475 FixedSunHour -= 24;
476 467
477 while (FixedSunHour < 0) 468 if (m_scene.RegionInfo.RegionSettings.UseEstateSun)
478 FixedSunHour += 24; 469 {
470 sunFixedHour = (float)m_scene.RegionInfo.EstateSettings.SunPosition;
471 fixedSun = m_scene.RegionInfo.EstateSettings.FixedSun;
472 }
473 else
474 {
475 sunFixedHour = (float)m_scene.RegionInfo.RegionSettings.SunPosition - 6.0f;
476 fixedSun = m_scene.RegionInfo.RegionSettings.FixedSun;
477 }
478
479 // Must limit the Sun Hour to 0 ... 24
480 while (sunFixedHour > 24.0f)
481 sunFixedHour -= 24;
479 482
480 m_SunFixedHour = FixedSunHour; 483 while (sunFixedHour < 0)
481 m_SunFixed = FixedSun; 484 sunFixedHour += 24;
485
486 m_SunFixedHour = sunFixedHour;
487 m_SunFixed = fixedSun;
482 488
483 // m_log.DebugFormat("[SUN]: Sun Settings Update: Fixed Sun? : {0}", m_SunFixed.ToString()); 489 // m_log.DebugFormat("[SUN]: Sun Settings Update: Fixed Sun? : {0}", m_SunFixed.ToString());
484 // m_log.DebugFormat("[SUN]: Sun Settings Update: Sun Hour : {0}", m_SunFixedHour.ToString()); 490 // m_log.DebugFormat("[SUN]: Sun Settings Update: Sun Hour : {0}", m_SunFixedHour.ToString());
@@ -501,7 +507,7 @@ namespace OpenSim.Region.CoreModules
501 { 507 {
502 m_scene.ForEachRootClient(delegate(IClientAPI client) 508 m_scene.ForEachRootClient(delegate(IClientAPI client)
503 { 509 {
504 SunToClient(client); 510 SunToClient(client);
505 }); 511 });
506 } 512 }
507 513
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 33aabe4..4d738a5 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -480,7 +480,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
480 else 480 else
481 { 481 {
482 m_plugineffects[pluginName] = effect; 482 m_plugineffects[pluginName] = effect;
483 m_log.Warn("E ... " + pluginName + " (Replaced)"); 483 m_log.Info("E ... " + pluginName + " (Replaced)");
484 } 484 }
485 } 485 }
486 } 486 }
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs
index 3d4f762..be719ea 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs
@@ -30,11 +30,12 @@ using NUnit.Framework;
30using OpenSim.Framework; 30using OpenSim.Framework;
31using OpenSim.Region.CoreModules.World.Terrain.PaintBrushes; 31using OpenSim.Region.CoreModules.World.Terrain.PaintBrushes;
32using OpenSim.Region.Framework.Scenes; 32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Tests.Common;
33 34
34namespace OpenSim.Region.CoreModules.World.Terrain.Tests 35namespace OpenSim.Region.CoreModules.World.Terrain.Tests
35{ 36{
36 [TestFixture] 37 [TestFixture]
37 public class TerrainTest 38 public class TerrainTest : OpenSimTestCase
38 { 39 {
39 [Test] 40 [Test]
40 public void BrushTest() 41 public void BrushTest()
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index 7ef44db..d38f34b 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
@@ -74,8 +74,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
74 { 74 {
75 m_config = source; 75 m_config = source;
76 76
77 IConfig startupConfig = m_config.Configs["Startup"]; 77 if (Util.GetConfigVarFromSections<string>(
78 if (startupConfig.GetString("MapImageModule", "MapImageModule") != "Warp3DImageModule") 78 m_config, "MapImageModule", new string[] { "Startup", "Map" }, "MapImageModule") != "Warp3DImageModule")
79 return; 79 return;
80 80
81 m_Enabled = true; 81 m_Enabled = true;
@@ -157,16 +157,12 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
157 bool drawPrimVolume = true; 157 bool drawPrimVolume = true;
158 bool textureTerrain = true; 158 bool textureTerrain = true;
159 159
160 try 160 string[] configSections = new string[] { "Map", "Startup" };
161 { 161
162 IConfig startupConfig = m_config.Configs["Startup"]; 162 drawPrimVolume
163 drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", drawPrimVolume); 163 = Util.GetConfigVarFromSections<bool>(m_config, "DrawPrimOnMapTile", configSections, drawPrimVolume);
164 textureTerrain = startupConfig.GetBoolean("TextureOnMapTile", textureTerrain); 164 textureTerrain
165 } 165 = Util.GetConfigVarFromSections<bool>(m_config, "TextureOnMapTile", configSections, textureTerrain);
166 catch
167 {
168 m_log.Warn("[WARP 3D IMAGE MODULE]: Failed to load StartupConfig");
169 }
170 166
171 m_colors.Clear(); 167 m_colors.Clear();
172 168
diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
index fd8e2b4..9de588c 100644
--- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
+++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules
66 public void Initialise(IConfigSource config) 66 public void Initialise(IConfigSource config)
67 { 67 {
68 m_windConfig = config.Configs["Wind"]; 68 m_windConfig = config.Configs["Wind"];
69 string desiredWindPlugin = m_dWindPluginName; 69// string desiredWindPlugin = m_dWindPluginName;
70 70
71 if (m_windConfig != null) 71 if (m_windConfig != null)
72 { 72 {
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 2184a59..bf18616 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -89,11 +89,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
89 #region INonSharedRegionModule Members 89 #region INonSharedRegionModule Members
90 public virtual void Initialise (IConfigSource config) 90 public virtual void Initialise (IConfigSource config)
91 { 91 {
92 IConfig startupConfig = config.Configs["Startup"]; 92 string[] configSections = new string[] { "Map", "Startup" };
93 if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap")
94 m_Enabled = true;
95 93
96 blacklistTimeout = startupConfig.GetInt("BlacklistTimeout", 10*60) * 1000; 94 if (Util.GetConfigVarFromSections<string>(
95 config, "WorldMapModule", configSections, "WorldMap") == "WorldMap")
96 m_Enabled = true;
97
98 blacklistTimeout
99 = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000;
97 } 100 }
98 101
99 public virtual void AddRegion (Scene scene) 102 public virtual void AddRegion (Scene scene)