aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
authorMelanie2013-04-28 19:03:39 +0200
committerMelanie2013-04-28 19:03:39 +0200
commit4275d7a839d7380ee50aeadc38a31dd467bd891e (patch)
tree1e589fc3b448b580d1cc25b52215ef5ce2d7ae78 /OpenSim/Region/CoreModules
parentMerge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork (diff)
parentController module for dynamic floaters (WIP) (diff)
downloadopensim-SC-4275d7a839d7380ee50aeadc38a31dd467bd891e.zip
opensim-SC-4275d7a839d7380ee50aeadc38a31dd467bd891e.tar.gz
opensim-SC-4275d7a839d7380ee50aeadc38a31dd467bd891e.tar.bz2
opensim-SC-4275d7a839d7380ee50aeadc38a31dd467bd891e.tar.xz
Merge branch 'avination-current' of ssh://3dhosting.de/var/git/careminster into avination-current
Conflicts: bin/Regions/Regions.ini.example
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs21
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs177
-rw-r--r--OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs687
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs283
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs289
-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/CallingCardModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs13
-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.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs41
-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.cs542
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs141
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs6
-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/InventoryAccessModule.cs7
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs10
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs1
-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/HttpRequest/ScriptsHttpRequests.cs79
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs87
-rw-r--r--OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs4
-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.cs36
-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/LightShare/LightShareModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs73
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs55
-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
75 files changed, 3473 insertions, 1414 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/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index 0aa4693..ffff37d 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -34,6 +34,7 @@ using OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
37using PermissionMask = OpenSim.Framework.PermissionMask;
37 38
38namespace OpenSim.Region.CoreModules.Agent.AssetTransaction 39namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
39{ 40{
@@ -260,10 +261,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
260 { 261 {
261 CompleteTaskItemUpdate(m_updateTaskItemData); 262 CompleteTaskItemUpdate(m_updateTaskItemData);
262 } 263 }
263// else if (m_storeLocal) 264 else if (m_asset.Local)
264// { 265 {
265// m_Scene.AssetService.Store(m_asset); 266 m_Scene.AssetService.Store(m_asset);
266// } 267 }
267 } 268 }
268 269
269 m_log.DebugFormat( 270 m_log.DebugFormat(
@@ -339,7 +340,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
339 // to avoid a race condition when the appearance module retrieves the item to set the asset id in 340 // to avoid a race condition when the appearance module retrieves the item to set the asset id in
340 // the AvatarAppearance structure. 341 // the AvatarAppearance structure.
341 item.AssetID = m_asset.FullID; 342 item.AssetID = m_asset.FullID;
342 m_Scene.InventoryService.UpdateItem(item); 343 if (item.AssetID != UUID.Zero)
344 m_Scene.InventoryService.UpdateItem(item);
343 345
344 if (m_uploadState == UploadState.Complete) 346 if (m_uploadState == UploadState.Complete)
345 { 347 {
@@ -390,6 +392,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
390// m_asset.FullID, item.Name, ourClient.Name); 392// m_asset.FullID, item.Name, ourClient.Name);
391 393
392 m_Scene.AssetService.Store(m_asset); 394 m_Scene.AssetService.Store(m_asset);
395 if (m_asset.FullID != UUID.Zero)
396 {
397 item.AssetID = m_asset.FullID;
398 m_Scene.InventoryService.UpdateItem(item);
399 }
393 400
394 m_transactions.RemoveXferUploader(m_transactionID); 401 m_transactions.RemoveXferUploader(m_transactionID);
395 } 402 }
@@ -424,8 +431,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
424 item.AssetType = type; 431 item.AssetType = type;
425 item.InvType = invType; 432 item.InvType = invType;
426 item.Folder = InventFolder; 433 item.Folder = InventFolder;
427 item.BasePermissions = 0x7fffffff; 434 item.BasePermissions = (uint)(PermissionMask.All | PermissionMask.Export);
428 item.CurrentPermissions = 0x7fffffff; 435 item.CurrentPermissions = item.BasePermissions;
429 item.GroupPermissions=0; 436 item.GroupPermissions=0;
430 item.EveryOnePermissions=0; 437 item.EveryOnePermissions=0;
431 item.NextPermissions = nextPerm; 438 item.NextPermissions = nextPerm;
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index a0f1e8c..d510d82 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -363,12 +363,37 @@ 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 string filename = GetFileName(id);
370
371#if WAIT_ON_INPROGRESS_REQUESTS
372 // Check if we're already downloading this asset. If so, try to wait for it to
373 // download.
374 if (m_WaitOnInprogressTimeout > 0)
375 {
376 m_RequestsForInprogress++;
377
378 ManualResetEvent waitEvent;
379 if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent))
380 {
381 waitEvent.WaitOne(m_WaitOnInprogressTimeout);
382 return Get(id);
383 }
384 }
385#else
386 // Track how often we have the problem that an asset is requested while
387 // it is still being downloaded by a previous request.
388 if (m_CurrentlyWriting.Contains(filename))
389 {
390 m_RequestsForInprogress++;
391 return null;
392 }
393#endif
394
369 AssetBase asset = null; 395 AssetBase asset = null;
370 396
371 string filename = GetFileName(id);
372 if (File.Exists(filename)) 397 if (File.Exists(filename))
373 { 398 {
374 FileStream stream = null; 399 FileStream stream = null;
@@ -383,7 +408,7 @@ namespace OpenSim.Region.CoreModules.Asset
383 } 408 }
384 catch (System.Runtime.Serialization.SerializationException e) 409 catch (System.Runtime.Serialization.SerializationException e)
385 { 410 {
386 m_log.ErrorFormat( 411 m_log.WarnFormat(
387 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 412 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
388 filename, id, e.Message, e.StackTrace); 413 filename, id, e.Message, e.StackTrace);
389 414
@@ -395,9 +420,10 @@ namespace OpenSim.Region.CoreModules.Asset
395 } 420 }
396 catch (Exception e) 421 catch (Exception e)
397 { 422 {
398 m_log.ErrorFormat( 423 m_log.WarnFormat(
399 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 424 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
400 filename, id, e.Message, e.StackTrace); 425 filename, id, e.Message, e.StackTrace);
426
401 } 427 }
402 finally 428 finally
403 { 429 {
@@ -406,28 +432,6 @@ namespace OpenSim.Region.CoreModules.Asset
406 } 432 }
407 } 433 }
408 434
409#if WAIT_ON_INPROGRESS_REQUESTS
410 // Check if we're already downloading this asset. If so, try to wait for it to
411 // download.
412 if (m_WaitOnInprogressTimeout > 0)
413 {
414 m_RequestsForInprogress++;
415
416 ManualResetEvent waitEvent;
417 if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent))
418 {
419 waitEvent.WaitOne(m_WaitOnInprogressTimeout);
420 return Get(id);
421 }
422 }
423#else
424 // Track how often we have the problem that an asset is requested while
425 // it is still being downloaded by a previous request.
426 if (m_CurrentlyWriting.Contains(filename))
427 {
428 m_RequestsForInprogress++;
429 }
430#endif
431 return asset; 435 return asset;
432 } 436 }
433 437
@@ -552,7 +556,7 @@ namespace OpenSim.Region.CoreModules.Asset
552 } 556 }
553 catch (Exception e) 557 catch (Exception e)
554 { 558 {
555 m_log.ErrorFormat( 559 m_log.WarnFormat(
556 "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}", 560 "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}",
557 id, e.Message, e.StackTrace); 561 id, e.Message, e.StackTrace);
558 } 562 }
@@ -603,29 +607,39 @@ namespace OpenSim.Region.CoreModules.Asset
603 /// <param name="purgeLine"></param> 607 /// <param name="purgeLine"></param>
604 private void CleanExpiredFiles(string dir, DateTime purgeLine) 608 private void CleanExpiredFiles(string dir, DateTime purgeLine)
605 { 609 {
606 foreach (string file in Directory.GetFiles(dir)) 610 try
607 { 611 {
608 if (File.GetLastAccessTime(file) < purgeLine) 612 foreach (string file in Directory.GetFiles(dir))
609 { 613 {
610 File.Delete(file); 614 if (File.GetLastAccessTime(file) < purgeLine)
615 {
616 File.Delete(file);
617 }
611 } 618 }
612 }
613 619
614 // Recurse into lower tiers 620 // Recurse into lower tiers
615 foreach (string subdir in Directory.GetDirectories(dir)) 621 foreach (string subdir in Directory.GetDirectories(dir))
616 { 622 {
617 CleanExpiredFiles(subdir, purgeLine); 623 CleanExpiredFiles(subdir, purgeLine);
618 } 624 }
619 625
620 // Check if a tier directory is empty, if so, delete it 626 // Check if a tier directory is empty, if so, delete it
621 int dirSize = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length; 627 int dirSize = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length;
622 if (dirSize == 0) 628 if (dirSize == 0)
623 { 629 {
624 Directory.Delete(dir); 630 Directory.Delete(dir);
631 }
632 else if (dirSize >= m_CacheWarnAt)
633 {
634 m_log.WarnFormat(
635 "[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration",
636 dir, dirSize);
637 }
625 } 638 }
626 else if (dirSize >= m_CacheWarnAt) 639 catch (Exception e)
627 { 640 {
628 m_log.WarnFormat("[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration", dir, dirSize); 641 m_log.Warn(
642 string.Format("[FLOTSAM ASSET CACHE]: Could not complete clean of expired files in {0}, exception ", dir), e);
629 } 643 }
630 } 644 }
631 645
@@ -684,7 +698,7 @@ namespace OpenSim.Region.CoreModules.Asset
684 } 698 }
685 catch (IOException e) 699 catch (IOException e)
686 { 700 {
687 m_log.ErrorFormat( 701 m_log.WarnFormat(
688 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.", 702 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.",
689 asset.ID, tempname, filename, directory, e.Message, e.StackTrace); 703 asset.ID, tempname, filename, directory, e.Message, e.StackTrace);
690 704
@@ -763,17 +777,31 @@ namespace OpenSim.Region.CoreModules.Asset
763 /// <summary> 777 /// <summary>
764 /// This notes the last time the Region had a deep asset scan performed on it. 778 /// This notes the last time the Region had a deep asset scan performed on it.
765 /// </summary> 779 /// </summary>
766 /// <param name="RegionID"></param> 780 /// <param name="regionID"></param>
767 private void StampRegionStatusFile(UUID RegionID) 781 private void StampRegionStatusFile(UUID regionID)
768 { 782 {
769 string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + RegionID.ToString() + ".fac"); 783 string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + regionID.ToString() + ".fac");
770 if (File.Exists(RegionCacheStatusFile)) 784
785 try
771 { 786 {
772 File.SetLastWriteTime(RegionCacheStatusFile, DateTime.Now); 787 if (File.Exists(RegionCacheStatusFile))
788 {
789 File.SetLastWriteTime(RegionCacheStatusFile, DateTime.Now);
790 }
791 else
792 {
793 File.WriteAllText(
794 RegionCacheStatusFile,
795 "Please do not delete this file unless you are manually clearing your Flotsam Asset Cache.");
796 }
773 } 797 }
774 else 798 catch (Exception e)
775 { 799 {
776 File.WriteAllText(RegionCacheStatusFile, "Please do not delete this file unless you are manually clearing your Flotsam Asset Cache."); 800 m_log.Warn(
801 string.Format(
802 "[FLOTSAM ASSET CACHE]: Could not stamp region status file for region {0}. Exception ",
803 regionID),
804 e);
777 } 805 }
778 } 806 }
779 807
@@ -790,32 +818,43 @@ namespace OpenSim.Region.CoreModules.Asset
790 { 818 {
791 UuidGatherer gatherer = new UuidGatherer(m_AssetService); 819 UuidGatherer gatherer = new UuidGatherer(m_AssetService);
792 820
821 HashSet<UUID> uniqueUuids = new HashSet<UUID>();
793 Dictionary<UUID, AssetType> assets = new Dictionary<UUID, AssetType>(); 822 Dictionary<UUID, AssetType> assets = new Dictionary<UUID, AssetType>();
823
794 foreach (Scene s in m_Scenes) 824 foreach (Scene s in m_Scenes)
795 { 825 {
796 StampRegionStatusFile(s.RegionInfo.RegionID); 826 StampRegionStatusFile(s.RegionInfo.RegionID);
797 827
798 s.ForEachSOG(delegate(SceneObjectGroup e) 828 s.ForEachSOG(delegate(SceneObjectGroup e)
799 { 829 {
800 gatherer.GatherAssetUuids(e, assets); 830 gatherer.GatherAssetUuids(e, assets);
801 });
802 }
803 831
804 foreach (UUID assetID in assets.Keys) 832 foreach (UUID assetID in assets.Keys)
805 { 833 {
806 string filename = GetFileName(assetID.ToString()); 834 uniqueUuids.Add(assetID);
807 835
808 if (File.Exists(filename)) 836 string filename = GetFileName(assetID.ToString());
809 { 837
810 File.SetLastAccessTime(filename, DateTime.Now); 838 if (File.Exists(filename))
811 } 839 {
812 else if (storeUncached) 840 File.SetLastAccessTime(filename, DateTime.Now);
813 { 841 }
814 m_AssetService.Get(assetID.ToString()); 842 else if (storeUncached)
815 } 843 {
844 AssetBase cachedAsset = m_AssetService.Get(assetID.ToString());
845 if (cachedAsset == null && assets[assetID] != AssetType.Unknown)
846 m_log.DebugFormat(
847 "[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",
848 assetID, assets[assetID], e.Name, e.AbsolutePosition, s.Name);
849 }
850 }
851
852 assets.Clear();
853 });
816 } 854 }
817 855
818 return assets.Keys.Count; 856
857 return uniqueUuids.Count;
819 } 858 }
820 859
821 /// <summary> 860 /// <summary>
@@ -831,7 +870,7 @@ namespace OpenSim.Region.CoreModules.Asset
831 } 870 }
832 catch (Exception e) 871 catch (Exception e)
833 { 872 {
834 m_log.ErrorFormat( 873 m_log.WarnFormat(
835 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}", 874 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}",
836 dir, m_CacheDirectory, e.Message, e.StackTrace); 875 dir, m_CacheDirectory, e.Message, e.StackTrace);
837 } 876 }
@@ -845,7 +884,7 @@ namespace OpenSim.Region.CoreModules.Asset
845 } 884 }
846 catch (Exception e) 885 catch (Exception e)
847 { 886 {
848 m_log.ErrorFormat( 887 m_log.WarnFormat(
849 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}", 888 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}",
850 file, m_CacheDirectory, e.Message, e.StackTrace); 889 file, m_CacheDirectory, e.Message, e.StackTrace);
851 } 890 }
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 acd156e..cb724aa 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
49 { 49 {
50 #region INonSharedRegionModule 50 #region INonSharedRegionModule
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 public int DebugLevel { get; set; }
52 54
53 private Scene m_scene; 55 private Scene m_scene;
54 private IInventoryAccessModule m_invAccessModule; 56 private IInventoryAccessModule m_invAccessModule;
@@ -76,10 +78,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
76 m_scene.RegisterModuleInterface<IAttachmentsModule>(this); 78 m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
77 79
78 if (Enabled) 80 if (Enabled)
81 {
79 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 82 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
83 m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true);
84 m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false);
85
86 MainConsole.Instance.Commands.AddCommand(
87 "Debug",
88 false,
89 "debug attachments",
90 "debug attachments [0|1]",
91 "Turn on attachments debugging\n"
92 + " <= 0 - turns off debugging\n"
93 + " >= 1 - turns on attachment message logging\n",
94 HandleDebugAttachments);
95 }
80 96
81 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI 97 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI
82 } 98 }
99
100 private void HandleDebugAttachments(string module, string[] args)
101 {
102 int debugLevel;
103
104 if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel)))
105 {
106 MainConsole.Instance.OutputFormat("Usage: debug attachments [0|1]");
107 }
108 else
109 {
110 DebugLevel = debugLevel;
111 MainConsole.Instance.OutputFormat(
112 "Set event queue debug level to {0} in {1}", DebugLevel, m_scene.Name);
113 }
114 }
115
116 /// <summary>
117 /// Listen for client triggered running state changes so that we can persist the script's object if necessary.
118 /// </summary>
119 /// <param name='localID'></param>
120 /// <param name='itemID'></param>
121 private void HandleScriptStateChange(uint localID, bool started)
122 {
123 SceneObjectGroup sog = m_scene.GetGroupByPrim(localID);
124 if (sog != null && sog.IsAttachment)
125 {
126 if (!started)
127 {
128 // FIXME: This is a convoluted way for working out whether the script state has changed to stop
129 // because it has been manually stopped or because the stop was called in UpdateDetachedObject() below
130 // This needs to be handled in a less tangled way.
131 ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar);
132 if (sp.ControllingClient.IsActive)
133 sog.HasGroupChanged = true;
134 }
135 else
136 {
137 sog.HasGroupChanged = true;
138 }
139 }
140 }
83 141
84 public void RemoveRegion(Scene scene) 142 public void RemoveRegion(Scene scene)
85 { 143 {
@@ -153,10 +211,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
153 } 211 }
154 } 212 }
155 213
156 /// <summary>
157 /// RezAttachments. This should only be called upon login on the first region.
158 /// Attachment rezzings on crossings and TPs are done in a different way.
159 /// </summary>
160 public void RezAttachments(IScenePresence sp) 214 public void RezAttachments(IScenePresence sp)
161 { 215 {
162 if (!Enabled) 216 if (!Enabled)
@@ -165,10 +219,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
165 if (null == sp.Appearance) 219 if (null == sp.Appearance)
166 { 220 {
167 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); 221 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
222
168 return; 223 return;
169 } 224 }
170 225
171// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name); 226 if (sp.GetAttachments().Count > 0)
227 {
228 if (DebugLevel > 0)
229 m_log.DebugFormat(
230 "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments",
231 m_scene.Name, sp.Name);
232
233 return;
234 }
235
236 if (DebugLevel > 0)
237 m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name);
172 238
173 XmlDocument doc = new XmlDocument(); 239 XmlDocument doc = new XmlDocument();
174 string stateData = String.Empty; 240 string stateData = String.Empty;
@@ -235,10 +301,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
235 301
236 // If we're an NPC then skip all the item checks and manipulations since we don't have an 302 // If we're an NPC then skip all the item checks and manipulations since we don't have an
237 // inventory right now. 303 // inventory right now.
238 if (sp.PresenceType == PresenceType.Npc) 304 RezSingleAttachmentFromInventoryInternal(
239 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); 305 sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true, null);
240 else
241 RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d);
242 } 306 }
243 catch (Exception e) 307 catch (Exception e)
244 { 308 {
@@ -254,14 +318,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
254 if (!Enabled) 318 if (!Enabled)
255 return; 319 return;
256 320
257// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); 321 if (DebugLevel > 0)
322 m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
323
324 List<SceneObjectGroup> attachments = sp.GetAttachments();
325
326 if (attachments.Count <= 0)
327 return;
328
329 Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>();
330
331 foreach (SceneObjectGroup so in attachments)
332 {
333 // Scripts MUST be snapshotted before the object is
334 // removed from the scene because doing otherwise will
335 // clobber the run flag
336 // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from
337 // scripts performing attachment operations at the same time. Getting object states stops the scripts.
338 scriptStates[so] = PrepareScriptInstanceForSave(so, false);
339 }
258 340
259 lock (sp.AttachmentsSyncLock) 341 lock (sp.AttachmentsSyncLock)
260 { 342 {
261 foreach (SceneObjectGroup so in sp.GetAttachments()) 343 foreach (SceneObjectGroup so in attachments)
262 { 344 UpdateDetachedObject(sp, so, scriptStates[so]);
263 UpdateDetachedObject(sp, so);
264 }
265 345
266 sp.ClearAttachments(); 346 sp.ClearAttachments();
267 } 347 }
@@ -272,9 +352,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
272 if (!Enabled) 352 if (!Enabled)
273 return; 353 return;
274 354
275// m_log.DebugFormat( 355 if (DebugLevel > 0)
276// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", 356 m_log.DebugFormat(
277// m_scene.RegionInfo.RegionName, sp.Name, silent); 357 "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
358 m_scene.RegionInfo.RegionName, sp.Name, silent);
278 359
279 foreach (SceneObjectGroup sop in sp.GetAttachments()) 360 foreach (SceneObjectGroup sop in sp.GetAttachments())
280 { 361 {
@@ -284,131 +365,141 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
284 sp.ClearAttachments(); 365 sp.ClearAttachments();
285 } 366 }
286 367
287 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp) 368 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool append)
288 { 369 {
289 if (!Enabled) 370 if (!Enabled)
290 return false; 371 return false;
291 372
292 if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp)) 373 return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, addToInventory, false, append);
293 {
294 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
295 return true;
296 }
297
298 return false;
299 } 374 }
300 375
301 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp) 376 /// <summary>
377 /// Internal method which actually does all the work for attaching an object.
378 /// </summary>
379 /// <returns>The object attached.</returns>
380 /// <param name='sp'></param>
381 /// <param name='group'>The object to attach.</param>
382 /// <param name='attachmentPt'></param>
383 /// <param name='silent'></param>
384 /// <param name='addToInventory'>If true then add object to user inventory.</param>
385 /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param>
386 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool resumeScripts, bool append)
302 { 387 {
303 lock (sp.AttachmentsSyncLock)
304 {
305// m_log.DebugFormat( 388// m_log.DebugFormat(
306// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", 389// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
307// group.Name, group.LocalId, sp.Name, attachmentPt, silent); 390// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
308 391
309 if (group.GetSittingAvatarsCount() != 0) 392 if (sp.GetAttachments().Contains(group))
310 { 393 {
311// m_log.WarnFormat( 394// m_log.WarnFormat(
312// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", 395// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
313// group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); 396// group.Name, group.LocalId, sp.Name, AttachmentPt);
314 397
315 return false; 398 return false;
316 } 399 }
317 400
318 if (sp.GetAttachments(attachmentPt).Contains(group)) 401 if (group.GetSittingAvatarsCount() != 0)
319 { 402 {
320 // m_log.WarnFormat( 403 if (DebugLevel > 0)
321 // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", 404 m_log.WarnFormat(
322 // group.Name, group.LocalId, sp.Name, AttachmentPt); 405 "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it",
323 406 group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount());
324 return false; 407
325 } 408 return false;
326 409 }
327 Vector3 attachPos = group.AbsolutePosition; 410
328 411 Vector3 attachPos = group.AbsolutePosition;
329 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 412
330 // be removed when that functionality is implemented in opensim 413 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
331 attachmentPt &= 0x7f; 414 // be removed when that functionality is implemented in opensim
332 415 attachmentPt &= 0x7f;
333 // If the attachment point isn't the same as the one previously used 416
334 // set it's offset position = 0 so that it appears on the attachment point 417 // If the attachment point isn't the same as the one previously used
335 // and not in a weird location somewhere unknown. 418 // set it's offset position = 0 so that it appears on the attachment point
336 if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) 419 // and not in a weird location somewhere unknown.
337 { 420 if (attachmentPt != (uint)AttachmentPoint.Default && attachmentPt != group.AttachmentPoint)
338 attachPos = Vector3.Zero; 421 {
339 } 422 attachPos = Vector3.Zero;
340 423 }
341 // AttachmentPt 0 means the client chose to 'wear' the attachment. 424
342 if (attachmentPt == 0) 425 // AttachmentPt 0 (default) means the client chose to 'wear' the attachment.
343 { 426 if (attachmentPt == (uint)AttachmentPoint.Default)
344 // Check object for stored attachment point 427 {
345 attachmentPt = group.AttachmentPoint; 428 // Check object for stored attachment point
346 } 429 attachmentPt = group.AttachmentPoint;
347 430 }
348 // if we still didn't find a suitable attachment point....... 431
349 if (attachmentPt == 0) 432 // if we still didn't find a suitable attachment point.......
350 { 433 if (attachmentPt == 0)
351 // Stick it on left hand with Zero Offset from the attachment point. 434 {
352 attachmentPt = (uint)AttachmentPoint.LeftHand; 435 // Stick it on left hand with Zero Offset from the attachment point.
353 attachPos = Vector3.Zero; 436 attachmentPt = (uint)AttachmentPoint.LeftHand;
354 } 437 attachPos = Vector3.Zero;
355 438 }
356 if (useAttachData) 439
440 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
441
442 if (attachments.Contains(group))
443 {
444 if (DebugLevel > 0)
445 m_log.WarnFormat(
446 "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
447 group.Name, group.LocalId, sp.Name, attachmentPt);
448
449 return false;
450 }
451
452 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
453 while (attachments.Count >= 5)
454 {
455 if (attachments[0].FromItemID != UUID.Zero)
456 DetachSingleAttachmentToInv(sp, attachments[0]);
457 attachments.RemoveAt(0);
458 }
459
460 // If we're not appending, remove the rest as well
461 if (attachments.Count != 0 && !append)
462 {
463 foreach (SceneObjectGroup g in attachments)
357 { 464 {
358 group.RootPart.RotationOffset = group.RootPart.AttachRotation; 465 if (g.FromItemID != UUID.Zero)
359 attachPos = group.RootPart.AttachOffset; 466 DetachSingleAttachmentToInv(sp, g);
360 if (attachmentPt == 0)
361 {
362 attachmentPt = group.RootPart.AttachPoint;
363 if (attachmentPt == 0)
364 {
365 attachmentPt = (uint)AttachmentPoint.LeftHand;
366 attachPos = Vector3.Zero;
367 }
368 }
369 else if (group.RootPart.AttachPoint != attachmentPt)
370 {
371 attachPos = Vector3.Zero;
372 }
373 } 467 }
468 }
469
470 lock (sp.AttachmentsSyncLock)
471 {
374 group.AttachmentPoint = attachmentPt; 472 group.AttachmentPoint = attachmentPt;
375 group.AbsolutePosition = attachPos; 473 group.AbsolutePosition = attachPos;
376 474
377 if (sp.PresenceType != PresenceType.Npc) 475 if (addToInventory && sp.PresenceType != PresenceType.Npc)
378 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); 476 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
379 477
380 AttachToAgent(sp, group, attachmentPt, attachPos, silent); 478 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
479
480 if (resumeScripts)
481 {
482 // Fire after attach, so we don't get messy perms dialogs
483 // 4 == AttachedRez
484 group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
485 group.ResumeScripts();
486 }
487
488 // Do this last so that event listeners have access to all the effects of the attachment
489 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
381 } 490 }
382 491
383 return true; 492 return true;
384 } 493 }
385 494
386 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) 495 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool append)
387 { 496 {
388 // Remove any previous attachments
389 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
390
391 // At the moment we can only deal with a single attachment
392 if (attachments.Count != 0)
393 {
394 if (attachments[0].FromItemID != UUID.Zero)
395 DetachSingleAttachmentToInvInternal(sp, attachments[0]);
396 // Error logging commented because UUID.Zero now means temp attachment
397// else
398// m_log.WarnFormat(
399// "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
400// attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
401 }
402
403 // Add the new attachment to inventory if we don't already have it. 497 // Add the new attachment to inventory if we don't already have it.
404 if (!temp) 498 UUID newAttachmentItemID = group.FromItemID;
405 { 499 if (newAttachmentItemID == UUID.Zero)
406 UUID newAttachmentItemID = group.FromItemID; 500 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
407 if (newAttachmentItemID == UUID.Zero)
408 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
409 501
410 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); 502 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
411 }
412 } 503 }
413 504
414 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) 505 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
@@ -421,41 +512,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
421 if (!Enabled) 512 if (!Enabled)
422 return null; 513 return null;
423 514
424// m_log.DebugFormat( 515 if (DebugLevel > 0)
425// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", 516 m_log.DebugFormat(
426// (AttachmentPoint)AttachmentPt, itemID, sp.Name); 517 "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}",
427 518 (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name);
428 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
429 // be removed when that functionality is implemented in opensim
430 AttachmentPt &= 0x7f;
431 519
432 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). 520 // We check the attachments in the avatar appearance here rather than the objects attached to the
433 // This often happens during login - not sure the exact reason. 521 // ScenePresence itself so that we can ignore calls by viewer 2/3 to attach objects on startup. We are
434 // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the 522 // already doing this in ScenePresence.MakeRootAgent(). Simulator-side attaching needs to be done
435 // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login 523 // because pre-outfit folder viewers (most version 1 viewers) require it.
436 // before anything has actually been attached.
437 bool alreadyOn = false; 524 bool alreadyOn = false;
438 List<SceneObjectGroup> existingAttachments = sp.GetAttachments(); 525 List<AvatarAttachment> existingAttachments = sp.Appearance.GetAttachments();
439 foreach (SceneObjectGroup so in existingAttachments) 526 foreach (AvatarAttachment existingAttachment in existingAttachments)
440 { 527 {
441 if (so.FromItemID == itemID) 528 if (existingAttachment.ItemID == itemID)
442 { 529 {
443 alreadyOn = true; 530 alreadyOn = true;
444 break; 531 break;
445 } 532 }
446 } 533 }
447 534
448// if (sp.Appearance.GetAttachmentForItem(itemID) != null)
449 if (alreadyOn) 535 if (alreadyOn)
450 { 536 {
451// m_log.WarnFormat( 537 if (DebugLevel > 0)
452// "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", 538 m_log.DebugFormat(
453// sp.Name, itemID, AttachmentPt); 539 "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn",
540 sp.Name, itemID, AttachmentPt);
454 541
455 return null; 542 return null;
456 } 543 }
457 544
458 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); 545 bool append = (AttachmentPt & 0x80) != 0;
546 AttachmentPt &= 0x7f;
547
548 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append, doc);
459 } 549 }
460 550
461 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 551 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -463,13 +553,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
463 if (!Enabled) 553 if (!Enabled)
464 return; 554 return;
465 555
466 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); 556 if (DebugLevel > 0)
467 lock (sp.AttachmentsSyncLock) 557 m_log.DebugFormat(
558 "[ATTACHMENTS MODULE]: Rezzing {0} attachments from inventory for {1} in {2}",
559 rezlist.Count, sp.Name, m_scene.Name);
560
561 foreach (KeyValuePair<UUID, uint> rez in rezlist)
468 { 562 {
469 foreach (KeyValuePair<UUID, uint> rez in rezlist) 563 RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value);
470 {
471 RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value);
472 }
473 } 564 }
474 } 565 }
475 566
@@ -483,9 +574,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
483 if (!Enabled) 574 if (!Enabled)
484 return; 575 return;
485 576
486// m_log.DebugFormat( 577 if (DebugLevel > 0)
487// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", 578 m_log.DebugFormat(
488// sp.UUID, soLocalId); 579 "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
580 sp.UUID, soLocalId);
489 581
490 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); 582 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
491 583
@@ -501,9 +593,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
501 if (inventoryID == UUID.Zero) 593 if (inventoryID == UUID.Zero)
502 return; 594 return;
503 595
504// m_log.DebugFormat( 596 if (DebugLevel > 0)
505// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", 597 m_log.DebugFormat(
506// so.Name, so.LocalId, inventoryID); 598 "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
599 so.Name, so.LocalId, inventoryID);
507 600
508 lock (sp.AttachmentsSyncLock) 601 lock (sp.AttachmentsSyncLock)
509 { 602 {
@@ -549,25 +642,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
549 642
550 public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) 643 public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
551 { 644 {
645 if (so.AttachedAvatar != sp.UUID)
646 {
647 m_log.WarnFormat(
648 "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}",
649 so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName);
650
651 return;
652 }
653
654 if (DebugLevel > 0)
655 m_log.DebugFormat(
656 "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}",
657 so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name);
658
659 // Scripts MUST be snapshotted before the object is
660 // removed from the scene because doing otherwise will
661 // clobber the run flag
662 // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from
663 // scripts performing attachment operations at the same time. Getting object states stops the scripts.
664 string scriptedState = PrepareScriptInstanceForSave(so, true);
665
552 lock (sp.AttachmentsSyncLock) 666 lock (sp.AttachmentsSyncLock)
553 { 667 {
554 // Save avatar attachment information 668 // Save avatar attachment information
555// m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); 669// m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);
556 670
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); 671 bool changed = sp.Appearance.DetachAttachment(so.FromItemID);
567 if (changed && m_scene.AvatarFactory != null) 672 if (changed && m_scene.AvatarFactory != null)
568 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); 673 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
569 674
570 DetachSingleAttachmentToInvInternal(sp, so); 675 sp.RemoveAttachment(so);
676 UpdateDetachedObject(sp, so, scriptedState);
571 } 677 }
572 } 678 }
573 679
@@ -674,12 +780,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
674 780
675 grp.HasGroupChanged = false; // Prevent it being saved over and over 781 grp.HasGroupChanged = false; // Prevent it being saved over and over
676 } 782 }
677// else 783 else if (DebugLevel > 0)
678// { 784 {
679// m_log.DebugFormat( 785 m_log.DebugFormat(
680// "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", 786 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
681// grp.UUID, grp.AttachmentPoint); 787 grp.UUID, grp.AttachmentPoint);
682// } 788 }
683 } 789 }
684 790
685 /// <summary> 791 /// <summary>
@@ -697,9 +803,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
697 private void AttachToAgent( 803 private void AttachToAgent(
698 IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) 804 IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
699 { 805 {
700// m_log.DebugFormat( 806 if (DebugLevel > 0)
701// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", 807 m_log.DebugFormat(
702// so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); 808 "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
809 so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
703 810
704 so.DetachFromBackup(); 811 so.DetachFromBackup();
705 812
@@ -722,19 +829,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
722 829
723 if (!silent) 830 if (!silent)
724 { 831 {
725 // Killing it here will cause the client to deselect it 832 if (so.HasPrivateAttachmentPoint)
726 // It then reappears on the avatar, deselected
727 // through the full update below
728 //
729 if (so.IsSelected)
730 { 833 {
731 m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId }); 834 if (DebugLevel > 0)
732 } 835 m_log.DebugFormat(
733 else if (so.HasPrivateAttachmentPoint) 836 "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}",
734 { 837 so.Name, sp.Name, so.AttachmentPoint);
735// m_log.DebugFormat(
736// "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}",
737// so.Name, sp.Name, so.AttachmentPoint);
738 838
739 // As this scene object can now only be seen by the attaching avatar, tell everybody else in the 839 // As this scene object can now only be seen by the attaching avatar, tell everybody else in the
740 // scene that it's no longer in their awareness. 840 // scene that it's no longer in their awareness.
@@ -745,7 +845,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
745 }); 845 });
746 } 846 }
747 847
748 so.IsSelected = false; // fudge.... 848 // Fudge below is an extremely unhelpful comment. It's probably here so that the scheduled full update
849 // will succeed, as that will not update if an attachment is selected.
850 so.IsSelected = false; // fudge....
851
749 so.ScheduleGroupForFullUpdate(); 852 so.ScheduleGroupForFullUpdate();
750 } 853 }
751 854
@@ -765,9 +868,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
765 if (m_invAccessModule == null) 868 if (m_invAccessModule == null)
766 return null; 869 return null;
767 870
768 // m_log.DebugFormat( 871 if (DebugLevel > 0)
769 // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", 872 m_log.DebugFormat(
770 // grp.Name, grp.LocalId, remoteClient.Name); 873 "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
874 grp.Name, grp.LocalId, sp.Name);
771 875
772 InventoryItemBase newItem 876 InventoryItemBase newItem
773 = m_invAccessModule.CopyToInventory( 877 = m_invAccessModule.CopyToInventory(
@@ -782,8 +886,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
782 return newItem; 886 return newItem;
783 } 887 }
784 888
785 private string GetObjectScriptStates(SceneObjectGroup grp) 889 /// <summary>
890 /// Prepares the script instance for save.
891 /// </summary>
892 /// <remarks>
893 /// This involves triggering the detach event and getting the script state (which also stops the script)
894 /// This MUST be done outside sp.AttachmentsSyncLock, since otherwise there is a chance of deadlock if a
895 /// running script is performing attachment operations.
896 /// </remarks>
897 /// <returns>
898 /// The script state ready for persistence.
899 /// </returns>
900 /// <param name='grp'>
901 /// </param>
902 /// <param name='fireDetachEvent'>
903 /// If true, then fire the script event before we save its state.
904 /// </param>
905 private string PrepareScriptInstanceForSave(SceneObjectGroup grp, bool fireDetachEvent)
786 { 906 {
907 if (fireDetachEvent)
908 m_scene.EventManager.TriggerOnAttach(grp.LocalId, grp.FromItemID, UUID.Zero);
909
787 using (StringWriter sw = new StringWriter()) 910 using (StringWriter sw = new StringWriter())
788 { 911 {
789 using (XmlTextWriter writer = new XmlTextWriter(sw)) 912 using (XmlTextWriter writer = new XmlTextWriter(sw))
@@ -795,7 +918,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
795 } 918 }
796 } 919 }
797 920
798 private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so) 921 private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so, string scriptedState)
799 { 922 {
800 // Don't save attachments for HG visitors, it 923 // Don't save attachments for HG visitors, it
801 // messes up their inventory. When a HG visitor logs 924 // messes up their inventory. When a HG visitor logs
@@ -808,11 +931,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
808 && (m_scene.UserManagementModule == null 931 && (m_scene.UserManagementModule == null
809 || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID)); 932 || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
810 933
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 934 // Remove the object from the scene so no more updates
817 // are sent. Doing this before the below changes will ensure 935 // are sent. Doing this before the below changes will ensure
818 // updates can't cause "HUD artefacts" 936 // updates can't cause "HUD artefacts"
@@ -836,97 +954,75 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
836 so.RemoveScriptInstances(true); 954 so.RemoveScriptInstances(true);
837 } 955 }
838 956
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( 957 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
850 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc) 958 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append, XmlDocument doc)
851 { 959 {
852 if (m_invAccessModule == null) 960 if (m_invAccessModule == null)
853 return null; 961 return null;
854 962
855 lock (sp.AttachmentsSyncLock) 963 SceneObjectGroup objatt;
964
965 if (itemID != UUID.Zero)
966 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
967 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
968 false, false, sp.UUID, true);
969 else
970 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
971 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
972 false, false, sp.UUID, true);
973
974 if (objatt == null)
856 { 975 {
857 SceneObjectGroup objatt; 976 m_log.WarnFormat(
977 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
978 itemID, sp.Name, attachmentPt);
858 979
859 if (itemID != UUID.Zero) 980 return null;
860 objatt = m_invAccessModule.RezObject(sp.ControllingClient, 981 }
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 982
868 if (objatt != null) 983 if (DebugLevel > 0)
984 m_log.DebugFormat(
985 "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}",
986 objatt.Name, sp.Name, attachmentPt, m_scene.Name);
987
988 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
989 objatt.HasGroupChanged = false;
990 bool tainted = false;
991 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
992 tainted = true;
993
994 // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal
995 // course of events. If not, then it's probably not worth trying to recover the situation
996 // since this is more likely to trigger further exceptions and confuse later debugging. If
997 // exceptions can be thrown in expected error conditions (not NREs) then make this consistent
998 // since other normal error conditions will simply return false instead.
999 // This will throw if the attachment fails
1000 try
1001 {
1002 if (doc != null)
869 { 1003 {
870// m_log.DebugFormat( 1004 objatt.LoadScriptState(doc);
871// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", 1005 objatt.ResetOwnerChangeFlag();
872// objatt.Name, sp.Name, attachmentPt, m_scene.Name); 1006 }
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);
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 1007
905 if (doc != null) 1008 AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, true, append);
906 { 1009 }
907 objatt.LoadScriptState(doc); 1010 catch (Exception e)
908 objatt.ResetOwnerChangeFlag(); 1011 {
909 } 1012 m_log.ErrorFormat(
1013 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
1014 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
910 1015
911 // Fire after attach, so we don't get messy perms dialogs 1016 // Make sure the object doesn't stick around and bail
912 // 4 == AttachedRez 1017 sp.RemoveAttachment(objatt);
913 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); 1018 m_scene.DeleteSceneObject(objatt, false);
914 objatt.ResumeScripts(); 1019 return null;
1020 }
915 1021
916 // Do this last so that event listeners have access to all the effects of the attachment 1022 if (tainted)
917 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); 1023 objatt.HasGroupChanged = true;
918 1024
919 return objatt; 1025 return objatt;
920 }
921 else
922 {
923 m_log.WarnFormat(
924 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
925 itemID, sp.Name, attachmentPt);
926 }
927 }
928
929 return null;
930 } 1026 }
931 1027
932 /// <summary> 1028 /// <summary>
@@ -936,7 +1032,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
936 /// <param name="AttachmentPt"></param> 1032 /// <param name="AttachmentPt"></param>
937 /// <param name="itemID"></param> 1033 /// <param name="itemID"></param>
938 /// <param name="att"></param> 1034 /// <param name="att"></param>
939 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 1035 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att, bool append)
940 { 1036 {
941// m_log.DebugFormat( 1037// m_log.DebugFormat(
942// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 1038// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
@@ -959,12 +1055,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
959 if (item == null) 1055 if (item == null)
960 return; 1056 return;
961 1057
962 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 1058 int attFlag = append ? 0x80 : 0;
1059 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID);
963 if (changed && m_scene.AvatarFactory != null) 1060 if (changed && m_scene.AvatarFactory != null)
964 { 1061 {
965// m_log.DebugFormat( 1062 if (DebugLevel > 0)
966// "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", 1063 m_log.DebugFormat(
967// sp.Name, att.Name, AttachmentPt); 1064 "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()",
1065 sp.Name, att.Name, AttachmentPt);
968 1066
969 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); 1067 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
970 } 1068 }
@@ -979,9 +1077,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
979 if (!Enabled) 1077 if (!Enabled)
980 return null; 1078 return null;
981 1079
982 // m_log.DebugFormat( 1080 if (DebugLevel > 0)
983 // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", 1081 m_log.DebugFormat(
984 // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); 1082 "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}",
1083 (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name);
985 1084
986 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); 1085 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
987 1086
@@ -1012,9 +1111,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1012 1111
1013 private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) 1112 private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
1014 { 1113 {
1015// m_log.DebugFormat( 1114 if (DebugLevel > 0)
1016// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", 1115 m_log.DebugFormat(
1017// objectLocalID, remoteClient.Name, AttachmentPt, silent); 1116 "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
1117 objectLocalID, remoteClient.Name, AttachmentPt, silent);
1018 1118
1019 if (!Enabled) 1119 if (!Enabled)
1020 return; 1120 return;
@@ -1043,16 +1143,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1043 return; 1143 return;
1044 } 1144 }
1045 1145
1046 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 1146 bool append = (AttachmentPt & 0x80) != 0;
1047 // be removed when that functionality is implemented in opensim
1048 AttachmentPt &= 0x7f; 1147 AttachmentPt &= 0x7f;
1049 1148
1050 // Calls attach with a Zero position 1149 // Calls attach with a Zero position
1051 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false)) 1150 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, false, append))
1052 { 1151 {
1053// m_log.Debug( 1152 if (DebugLevel > 0)
1054// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId 1153 m_log.Debug(
1055// + ", AttachmentPoint: " + AttachmentPt); 1154 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
1155 + ", AttachmentPoint: " + AttachmentPt);
1056 1156
1057 // Save avatar attachment information 1157 // Save avatar attachment information
1058 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); 1158 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
@@ -1084,17 +1184,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1084 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); 1184 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
1085 if (sp != null) 1185 if (sp != null)
1086 { 1186 {
1087 lock (sp.AttachmentsSyncLock) 1187 List<SceneObjectGroup> attachments = sp.GetAttachments();
1188
1189 foreach (SceneObjectGroup group in attachments)
1088 { 1190 {
1089 List<SceneObjectGroup> attachments = sp.GetAttachments(); 1191 if (group.FromItemID == itemID && group.FromItemID != UUID.Zero)
1090
1091 foreach (SceneObjectGroup group in attachments)
1092 { 1192 {
1093 if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) 1193 DetachSingleAttachmentToInv(sp, group);
1094 { 1194 return;
1095 DetachSingleAttachmentToInv(sp, group);
1096 return;
1097 }
1098 } 1195 }
1099 } 1196 }
1100 } 1197 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 4e9d3f9..1a38619 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -130,7 +130,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
130 config.AddConfig("Modules"); 130 config.AddConfig("Modules");
131 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); 131 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
132 132
133 modules.Add(new AttachmentsModule()); 133 AttachmentsModule attMod = new AttachmentsModule();
134 attMod.DebugLevel = 1;
135 modules.Add(attMod);
134 modules.Add(new BasicInventoryAccessModule()); 136 modules.Add(new BasicInventoryAccessModule());
135 } 137 }
136 138
@@ -197,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
197 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); 199 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
198 200
199 m_numberOfAttachEventsFired = 0; 201 m_numberOfAttachEventsFired = 0;
200 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); 202 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false);
201 203
202 // Check status on scene presence 204 // Check status on scene presence
203 Assert.That(sp.HasAttachments(), Is.True); 205 Assert.That(sp.HasAttachments(), Is.True);
@@ -228,6 +230,120 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
228 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); 230 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
229 } 231 }
230 232
233 [Test]
234 public void TestWearAttachmentFromGround()
235 {
236 TestHelpers.InMethod();
237// TestHelpers.EnableLogging();
238
239 Scene scene = CreateTestScene();
240 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
241 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
242
243 SceneObjectGroup so2 = SceneHelpers.AddSceneObject(scene, "att2", sp.UUID);
244
245 {
246 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID);
247
248 m_numberOfAttachEventsFired = 0;
249 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false, false);
250
251 // Check status on scene presence
252 Assert.That(sp.HasAttachments(), Is.True);
253 List<SceneObjectGroup> attachments = sp.GetAttachments();
254 Assert.That(attachments.Count, Is.EqualTo(1));
255 SceneObjectGroup attSo = attachments[0];
256 Assert.That(attSo.Name, Is.EqualTo(so.Name));
257 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
258 Assert.That(attSo.IsAttachment);
259 Assert.That(attSo.UsesPhysics, Is.False);
260 Assert.That(attSo.IsTemporary, Is.False);
261
262 // Check item status
263 Assert.That(
264 sp.Appearance.GetAttachpoint(attSo.FromItemID),
265 Is.EqualTo((int)AttachmentPoint.LeftHand));
266
267 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
268 Assert.That(attachmentItem, Is.Not.Null);
269 Assert.That(attachmentItem.Name, Is.EqualTo(so.Name));
270
271 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
272 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
273
274 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2));
275
276 // Check events
277 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
278 }
279
280 // Test wearing a different attachment from the ground.
281 {
282 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false);
283
284 // Check status on scene presence
285 Assert.That(sp.HasAttachments(), Is.True);
286 List<SceneObjectGroup> attachments = sp.GetAttachments();
287 Assert.That(attachments.Count, Is.EqualTo(1));
288 SceneObjectGroup attSo = attachments[0];
289 Assert.That(attSo.Name, Is.EqualTo(so2.Name));
290 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
291 Assert.That(attSo.IsAttachment);
292 Assert.That(attSo.UsesPhysics, Is.False);
293 Assert.That(attSo.IsTemporary, Is.False);
294
295 // Check item status
296 Assert.That(
297 sp.Appearance.GetAttachpoint(attSo.FromItemID),
298 Is.EqualTo((int)AttachmentPoint.LeftHand));
299
300 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
301 Assert.That(attachmentItem, Is.Not.Null);
302 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
303
304 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
305 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
306
307 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
308
309 // Check events
310 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
311 }
312
313 // Test rewearing an already worn attachment from ground. Nothing should happen.
314 {
315 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false);
316
317 // Check status on scene presence
318 Assert.That(sp.HasAttachments(), Is.True);
319 List<SceneObjectGroup> attachments = sp.GetAttachments();
320 Assert.That(attachments.Count, Is.EqualTo(1));
321 SceneObjectGroup attSo = attachments[0];
322 Assert.That(attSo.Name, Is.EqualTo(so2.Name));
323 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
324 Assert.That(attSo.IsAttachment);
325 Assert.That(attSo.UsesPhysics, Is.False);
326 Assert.That(attSo.IsTemporary, Is.False);
327
328 // Check item status
329 Assert.That(
330 sp.Appearance.GetAttachpoint(attSo.FromItemID),
331 Is.EqualTo((int)AttachmentPoint.LeftHand));
332
333 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
334 Assert.That(attachmentItem, Is.Not.Null);
335 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
336
337 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
338 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
339
340 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
341
342 // Check events
343 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
344 }
345 }
346
231 /// <summary> 347 /// <summary>
232 /// Test that we do not attempt to attach an in-world object that someone else is sitting on. 348 /// Test that we do not attempt to attach an in-world object that someone else is sitting on.
233 /// </summary> 349 /// </summary>
@@ -254,7 +370,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
254 sp2.AbsolutePosition = new Vector3(0, 0, 0); 370 sp2.AbsolutePosition = new Vector3(0, 0, 0);
255 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); 371 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
256 372
257 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); 373 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false);
258 374
259 Assert.That(sp.HasAttachments(), Is.False); 375 Assert.That(sp.HasAttachments(), Is.False);
260 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 376 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -275,29 +391,140 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
275 391
276 InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); 392 InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
277 393
278 m_numberOfAttachEventsFired = 0; 394 {
279 scene.AttachmentsModule.RezSingleAttachmentFromInventory( 395 scene.AttachmentsModule.RezSingleAttachmentFromInventory(
280 sp, attItem.ID, (uint)AttachmentPoint.Chest); 396 sp, attItem.ID, (uint)AttachmentPoint.Chest);
281 397
282 // Check scene presence status 398 // Check scene presence status
283 Assert.That(sp.HasAttachments(), Is.True); 399 Assert.That(sp.HasAttachments(), Is.True);
284 List<SceneObjectGroup> attachments = sp.GetAttachments(); 400 List<SceneObjectGroup> attachments = sp.GetAttachments();
285 Assert.That(attachments.Count, Is.EqualTo(1)); 401 Assert.That(attachments.Count, Is.EqualTo(1));
286 SceneObjectGroup attSo = attachments[0]; 402 SceneObjectGroup attSo = attachments[0];
287 Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); 403 Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
288 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); 404 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
289 Assert.That(attSo.IsAttachment); 405 Assert.That(attSo.IsAttachment);
290 Assert.That(attSo.UsesPhysics, Is.False); 406 Assert.That(attSo.UsesPhysics, Is.False);
291 Assert.That(attSo.IsTemporary, Is.False); 407 Assert.That(attSo.IsTemporary, Is.False);
408
409 // Check appearance status
410 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
411 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
412 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
413
414 // Check events
415 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
416 }
417
418 // Test attaching an already attached attachment
419 {
420 scene.AttachmentsModule.RezSingleAttachmentFromInventory(
421 sp, attItem.ID, (uint)AttachmentPoint.Chest);
292 422
293 // Check appearance status 423 // Check scene presence status
294 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); 424 Assert.That(sp.HasAttachments(), Is.True);
295 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); 425 List<SceneObjectGroup> attachments = sp.GetAttachments();
426 Assert.That(attachments.Count, Is.EqualTo(1));
427 SceneObjectGroup attSo = attachments[0];
428 Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
429 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
430 Assert.That(attSo.IsAttachment);
431 Assert.That(attSo.UsesPhysics, Is.False);
432 Assert.That(attSo.IsTemporary, Is.False);
433
434 // Check appearance status
435 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
436 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
437 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
438
439 // Check events
440 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
441 }
442 }
296 443
297 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 444 /// <summary>
445 /// Test wearing an attachment from inventory, as opposed to explicit choosing the rez point
446 /// </summary>
447 [Test]
448 public void TestWearAttachmentFromInventory()
449 {
450 TestHelpers.InMethod();
451// TestHelpers.EnableLogging();
298 452
299 // Check events 453 Scene scene = CreateTestScene();
300 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); 454 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
455 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
456
457 InventoryItemBase attItem1 = CreateAttachmentItem(scene, ua1.PrincipalID, "att1", 0x10, 0x20);
458 InventoryItemBase attItem2 = CreateAttachmentItem(scene, ua1.PrincipalID, "att2", 0x11, 0x21);
459
460 {
461 m_numberOfAttachEventsFired = 0;
462 scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem1.ID, (uint)AttachmentPoint.Default);
463
464 // default attachment point is currently the left hand.
465 Assert.That(sp.HasAttachments(), Is.True);
466 List<SceneObjectGroup> attachments = sp.GetAttachments();
467 Assert.That(attachments.Count, Is.EqualTo(1));
468 SceneObjectGroup attSo = attachments[0];
469 Assert.That(attSo.Name, Is.EqualTo(attItem1.Name));
470 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
471 Assert.That(attSo.IsAttachment);
472
473 // Check appearance status
474 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
475 Assert.That(sp.Appearance.GetAttachpoint(attItem1.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
476 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
477
478 // Check events
479 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
480 }
481
482 // Test wearing a second attachment at the same position
483 // Until multiple attachments at one point is implemented, this will remove the first attachment
484 // This test relies on both attachments having the same default attachment point (in this case LeftHand
485 // since none other has been set).
486 {
487 scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default);
488
489 // default attachment point is currently the left hand.
490 Assert.That(sp.HasAttachments(), Is.True);
491 List<SceneObjectGroup> attachments = sp.GetAttachments();
492 Assert.That(attachments.Count, Is.EqualTo(1));
493 SceneObjectGroup attSo = attachments[0];
494 Assert.That(attSo.Name, Is.EqualTo(attItem2.Name));
495 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
496 Assert.That(attSo.IsAttachment);
497
498 // Check appearance status
499 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
500 Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
501 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
502
503 // Check events
504 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
505 }
506
507 // Test wearing an already attached attachment
508 {
509 scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default);
510
511 // default attachment point is currently the left hand.
512 Assert.That(sp.HasAttachments(), Is.True);
513 List<SceneObjectGroup> attachments = sp.GetAttachments();
514 Assert.That(attachments.Count, Is.EqualTo(1));
515 SceneObjectGroup attSo = attachments[0];
516 Assert.That(attSo.Name, Is.EqualTo(attItem2.Name));
517 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
518 Assert.That(attSo.IsAttachment);
519
520 // Check appearance status
521 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
522 Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
523 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
524
525 // Check events
526 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
527 }
301 } 528 }
302 529
303 /// <summary> 530 /// <summary>
@@ -503,7 +730,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
503 public void TestRezAttachmentsOnAvatarEntrance() 730 public void TestRezAttachmentsOnAvatarEntrance()
504 { 731 {
505 TestHelpers.InMethod(); 732 TestHelpers.InMethod();
506// log4net.Config.XmlConfigurator.Configure(); 733// TestHelpers.EnableLogging();
507 734
508 Scene scene = CreateTestScene(); 735 Scene scene = CreateTestScene();
509 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); 736 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
@@ -604,7 +831,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
604 sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); 831 sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
605 832
606 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); 833 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
607 ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager); 834
835 AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
836 TestClient tc = new TestClient(acd, sceneA, sh.SceneManager);
837 List<TestClient> destinationTestClients = new List<TestClient>();
838 EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients);
839
840 ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager);
608 beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); 841 beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
609 842
610 InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); 843 InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20);
@@ -623,7 +856,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
623 teleportLookAt, 856 teleportLookAt,
624 (uint)TeleportFlags.ViaLocation); 857 (uint)TeleportFlags.ViaLocation);
625 858
626 ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide(); 859 destinationTestClients[0].CompleteMovement();
627 860
628 // Check attachments have made it into sceneB 861 // Check attachments have made it into sceneB
629 ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); 862 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 7ec2860..bc79944 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -40,6 +40,7 @@ using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41 41
42using Mono.Addins; 42using Mono.Addins;
43using PermissionMask = OpenSim.Framework.PermissionMask;
43 44
44namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory 45namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
45{ 46{
@@ -322,6 +323,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
322 323
323 if (asset != null) 324 if (asset != null)
324 { 325 {
326 // Replace an HG ID with the simple asset ID so that we can persist textures for foreign HG avatars
327 asset.ID = asset.FullID.ToString();
328
325 asset.Temporary = false; 329 asset.Temporary = false;
326 asset.Local = false; 330 asset.Local = false;
327 m_scene.AssetService.Store(asset); 331 m_scene.AssetService.Store(asset);
@@ -358,7 +362,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
358 362
359 public void QueueAppearanceSave(UUID agentid) 363 public void QueueAppearanceSave(UUID agentid)
360 { 364 {
361 // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); 365// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
362 366
363 // 10000 ticks per millisecond, 1000 milliseconds per second 367 // 10000 ticks per millisecond, 1000 milliseconds per second
364 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); 368 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
@@ -655,7 +659,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
655 return; 659 return;
656 } 660 }
657 661
658 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); 662// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
659 663
660 // This could take awhile since it needs to pull inventory 664 // 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 665 // 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 +668,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
664 // multiple save requests. 668 // multiple save requests.
665 SetAppearanceAssets(sp.UUID, sp.Appearance); 669 SetAppearanceAssets(sp.UUID, sp.Appearance);
666 670
671// List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
672// foreach (AvatarAttachment att in attachments)
673// {
674// m_log.DebugFormat(
675// "[AVFACTORY]: For {0} saving attachment {1} at point {2}",
676// sp.Name, att.ItemID, att.AttachPoint);
677// }
678
667 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); 679 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
668 680
669 // Trigger this here because it's the final step in the set/queue/save process for appearance setting. 681 // Trigger this here because it's the final step in the set/queue/save process for appearance setting.
@@ -674,26 +686,70 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
674 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) 686 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
675 { 687 {
676 IInventoryService invService = m_scene.InventoryService; 688 IInventoryService invService = m_scene.InventoryService;
677 689 bool resetwearable = false;
678 if (invService.GetRootFolder(userID) != null) 690 if (invService.GetRootFolder(userID) != null)
679 { 691 {
680 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 692 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
681 { 693 {
682 for (int j = 0; j < appearance.Wearables[i].Count; j++) 694 for (int j = 0; j < appearance.Wearables[i].Count; j++)
683 { 695 {
696 // Check if the default wearables are not set
684 if (appearance.Wearables[i][j].ItemID == UUID.Zero) 697 if (appearance.Wearables[i][j].ItemID == UUID.Zero)
698 {
699 switch ((WearableType) i)
700 {
701 case WearableType.Eyes:
702 case WearableType.Hair:
703 case WearableType.Shape:
704 case WearableType.Skin:
705 //case WearableType.Underpants:
706 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
707 resetwearable = true;
708 m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
709 resetwearable = true;
710 break;
711
712 }
685 continue; 713 continue;
714 }
686 715
687 // Ignore ruth's assets 716 // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
688 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) 717 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
718 {
719 switch ((WearableType)i)
720 {
721 case WearableType.Eyes:
722 case WearableType.Hair:
723 case WearableType.Shape:
724 case WearableType.Skin:
725 //case WearableType.Underpants:
726 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
727
728 m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
729 resetwearable = true;
730 break;
731
732 }
689 continue; 733 continue;
690 734 }
735
691 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 736 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
692 baseItem = invService.GetItem(baseItem); 737 baseItem = invService.GetItem(baseItem);
693 738
694 if (baseItem != null) 739 if (baseItem != null)
695 { 740 {
696 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); 741 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
742 int unmodifiedWearableIndexForClosure = i;
743 m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
744 delegate(string x, object y, AssetBase z)
745 {
746 if (z == null)
747 {
748 TryAndRepairBrokenWearable(
749 (WearableType)unmodifiedWearableIndexForClosure, invService,
750 userID, appearance);
751 }
752 });
697 } 753 }
698 else 754 else
699 { 755 {
@@ -701,17 +757,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
701 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", 757 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
702 appearance.Wearables[i][j].ItemID, (WearableType)i); 758 appearance.Wearables[i][j].ItemID, (WearableType)i);
703 759
704 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); 760 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
761 resetwearable = true;
762
705 } 763 }
706 } 764 }
707 } 765 }
766
767 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
768 if (appearance.Wearables[(int) WearableType.Eyes] == null)
769 {
770 m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
771
772 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
773 resetwearable = true;
774 }
775 else
776 {
777 if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
778 {
779 m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
780 appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
781 appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
782 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
783 resetwearable = true;
784
785 }
786
787 }
788 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
789 if (appearance.Wearables[(int)WearableType.Shape] == null)
790 {
791 m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
792
793 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
794 resetwearable = true;
795 }
796 else
797 {
798 if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
799 {
800 m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
801 appearance.Wearables[(int)WearableType.Shape][0].ItemID,
802 appearance.Wearables[(int)WearableType.Shape][0].AssetID);
803 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
804 resetwearable = true;
805
806 }
807
808 }
809 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
810 if (appearance.Wearables[(int)WearableType.Hair] == null)
811 {
812 m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
813
814 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
815 resetwearable = true;
816 }
817 else
818 {
819 if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
820 {
821 m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
822 appearance.Wearables[(int)WearableType.Hair][0].ItemID,
823 appearance.Wearables[(int)WearableType.Hair][0].AssetID);
824 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
825 resetwearable = true;
826
827 }
828
829 }
830 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
831 if (appearance.Wearables[(int)WearableType.Skin] == null)
832 {
833 m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
834
835 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
836 resetwearable = true;
837 }
838 else
839 {
840 if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
841 {
842 m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
843 appearance.Wearables[(int)WearableType.Skin][0].ItemID,
844 appearance.Wearables[(int)WearableType.Skin][0].AssetID);
845 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
846 resetwearable = true;
847
848 }
849
850 }
851 if (resetwearable)
852 {
853 ScenePresence presence = null;
854 if (m_scene.TryGetScenePresence(userID, out presence))
855 {
856 presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
857 presence.Appearance.Serial++);
858 }
859 }
860
708 } 861 }
709 else 862 else
710 { 863 {
711 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); 864 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
712 } 865 }
713 } 866 }
867 private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
868 {
869 UUID defaultwearable = GetDefaultItem(type);
870 if (defaultwearable != UUID.Zero)
871 {
872 UUID newInvItem = UUID.Random();
873 InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID)
874 {
875 AssetID =
876 defaultwearable,
877 AssetType
878 =
879 (int)
880 AssetType
881 .Bodypart,
882 CreatorId
883 =
884 userID
885 .ToString
886 (),
887 //InvType = (int)InventoryType.Wearable,
888
889 Description
890 =
891 "Failed Wearable Replacement",
892 Folder =
893 invService
894 .GetFolderForType
895 (userID,
896 AssetType
897 .Bodypart)
898 .ID,
899 Flags = (uint) type,
900 Name = Enum.GetName(typeof (WearableType), type),
901 BasePermissions = (uint) PermissionMask.Copy,
902 CurrentPermissions = (uint) PermissionMask.Copy,
903 EveryOnePermissions = (uint) PermissionMask.Copy,
904 GroupPermissions = (uint) PermissionMask.Copy,
905 NextPermissions = (uint) PermissionMask.Copy
906 };
907 invService.AddItem(itembase);
908 UUID LinkInvItem = UUID.Random();
909 itembase = new InventoryItemBase(LinkInvItem, userID)
910 {
911 AssetID =
912 newInvItem,
913 AssetType
914 =
915 (int)
916 AssetType
917 .Link,
918 CreatorId
919 =
920 userID
921 .ToString
922 (),
923 InvType = (int) InventoryType.Wearable,
924
925 Description
926 =
927 "Failed Wearable Replacement",
928 Folder =
929 invService
930 .GetFolderForType
931 (userID,
932 AssetType
933 .CurrentOutfitFolder)
934 .ID,
935 Flags = (uint) type,
936 Name = Enum.GetName(typeof (WearableType), type),
937 BasePermissions = (uint) PermissionMask.Copy,
938 CurrentPermissions = (uint) PermissionMask.Copy,
939 EveryOnePermissions = (uint) PermissionMask.Copy,
940 GroupPermissions = (uint) PermissionMask.Copy,
941 NextPermissions = (uint) PermissionMask.Copy
942 };
943 invService.AddItem(itembase);
944 appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type));
945 ScenePresence presence = null;
946 if (m_scene.TryGetScenePresence(userID, out presence))
947 {
948 m_scene.SendInventoryUpdate(presence.ControllingClient,
949 invService.GetFolderForType(userID,
950 AssetType
951 .CurrentOutfitFolder),
952 false, true);
953 }
954 }
955 }
956 private UUID GetDefaultItem(WearableType wearable)
957 {
958 // These are ruth
959 UUID ret = UUID.Zero;
960 switch (wearable)
961 {
962 case WearableType.Eyes:
963 ret = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
964 break;
965 case WearableType.Hair:
966 ret = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
967 break;
968 case WearableType.Pants:
969 ret = new UUID("00000000-38f9-1111-024e-222222111120");
970 break;
971 case WearableType.Shape:
972 ret = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
973 break;
974 case WearableType.Shirt:
975 ret = new UUID("00000000-38f9-1111-024e-222222111110");
976 break;
977 case WearableType.Skin:
978 ret = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
979 break;
980 case WearableType.Undershirt:
981 ret = new UUID("16499ebb-3208-ec27-2def-481881728f47");
982 break;
983 case WearableType.Underpants:
984 ret = new UUID("4ac2e9c7-3671-d229-316a-67717730841d");
985 break;
986 }
714 987
988 return ret;
989 }
715 #endregion 990 #endregion
716 991
717 #region Client Event Handlers 992 #region Client Event Handlers
@@ -824,7 +1099,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
824 } 1099 }
825 1100
826 bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp); 1101 bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp);
827 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); 1102 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete");
828 } 1103 }
829 } 1104 }
830} 1105}
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/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
index 5ec0ea9..b44a5c9 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
@@ -36,6 +36,7 @@ using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
38using Mono.Addins; 38using Mono.Addins;
39using PermissionMask = OpenSim.Framework.PermissionMask;
39 40
40namespace OpenSim.Region.CoreModules.Avatar.Friends 41namespace OpenSim.Region.CoreModules.Avatar.Friends
41{ 42{
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/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 9fa9be1..fa8c3f3 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -67,9 +67,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
67 protected Scene m_scene; 67 protected Scene m_scene;
68 protected IDialogModule m_dialogModule; 68 protected IDialogModule m_dialogModule;
69 69
70 protected Dictionary<UUID, string> m_capsDict =
71 new Dictionary<UUID, string>();
72
73 protected IDialogModule DialogModule 70 protected IDialogModule DialogModule
74 { 71 {
75 get 72 get
@@ -91,7 +88,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
91 m_scene.RegisterModuleInterface<IGodsModule>(this); 88 m_scene.RegisterModuleInterface<IGodsModule>(this);
92 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 89 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
93 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; 90 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
94 m_scene.EventManager.OnClientClosed += OnClientClosed;
95 scene.EventManager.OnIncomingInstantMessage += 91 scene.EventManager.OnIncomingInstantMessage +=
96 OnIncomingInstantMessage; 92 OnIncomingInstantMessage;
97 } 93 }
@@ -127,15 +123,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
127 client.OnRequestGodlikePowers -= RequestGodlikePowers; 123 client.OnRequestGodlikePowers -= RequestGodlikePowers;
128 } 124 }
129 125
130 private void OnClientClosed(UUID agentID, Scene scene)
131 {
132 m_capsDict.Remove(agentID);
133 }
134
135 private void OnRegisterCaps(UUID agentID, Caps caps) 126 private void OnRegisterCaps(UUID agentID, Caps caps)
136 { 127 {
137 string uri = "/CAPS/" + UUID.Random(); 128 string uri = "/CAPS/" + UUID.Random();
138 m_capsDict[agentID] = uri;
139 129
140 caps.RegisterHandler("UntrustedSimulatorMessage", 130 caps.RegisterHandler("UntrustedSimulatorMessage",
141 new RestStreamHandler("POST", uri, 131 new RestStreamHandler("POST", uri,
@@ -288,8 +278,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
288 if (sp.IsChildAgent) 278 if (sp.IsChildAgent)
289 return; 279 return;
290 sp.ControllingClient.Kick(reason); 280 sp.ControllingClient.Kick(reason);
291 sp.MakeChildAgent(); 281 sp.Scene.IncomingCloseAgent(sp.UUID, true);
292 sp.ControllingClient.Close();
293 } 282 }
294 283
295 private void OnIncomingInstantMessage(GridInstantMessage msg) 284 private void OnIncomingInstantMessage(GridInstantMessage msg)
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..a34f2d2 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 }
@@ -151,7 +154,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
151 154
152 void OnIncomingInstantMessage(GridInstantMessage im) 155 void OnIncomingInstantMessage(GridInstantMessage im)
153 { 156 {
154 if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) 157 if (im.dialog == (byte)InstantMessageDialog.RequestTeleport
158 || im.dialog == (byte)InstantMessageDialog.GodLikeRequestTeleport)
155 { 159 {
156 UUID sessionID = new UUID(im.imSessionID); 160 UUID sessionID = new UUID(im.imSessionID);
157 161
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index f3adb95..0c64f19 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -165,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
165 (uint)presence.AbsolutePosition.Y, 165 (uint)presence.AbsolutePosition.Y,
166 (uint)presence.AbsolutePosition.Z + 2); 166 (uint)presence.AbsolutePosition.Z + 2);
167 167
168 m_log.DebugFormat("[LURE]: TP invite with message {0}", message); 168 m_log.DebugFormat("TP invite with message {0}, type {1}", message, lureType);
169 169
170 GridInstantMessage m; 170 GridInstantMessage m;
171 171
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 7f30e5a..2eb9bfb 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.Framework
55 /// <summary> 55 /// <summary>
56 /// Each agent has its own capabilities handler. 56 /// Each agent has its own capabilities handler.
57 /// </summary> 57 /// </summary>
58 protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>(); 58 protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>();
59 59
60 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>(); 60 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>();
61 protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds 61 protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds
@@ -100,7 +100,7 @@ namespace OpenSim.Region.CoreModules.Framework
100 get { return null; } 100 get { return null; }
101 } 101 }
102 102
103 public void CreateCaps(UUID agentId) 103 public void CreateCaps(UUID agentId, uint circuitCode)
104 { 104 {
105 int flags = m_scene.GetUserFlags(agentId); 105 int flags = m_scene.GetUserFlags(agentId);
106 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) 106 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
@@ -108,9 +108,9 @@ namespace OpenSim.Region.CoreModules.Framework
108 108
109 String capsObjectPath = GetCapsPath(agentId); 109 String capsObjectPath = GetCapsPath(agentId);
110 110
111 if (m_capsObjects.ContainsKey(agentId)) 111 if (m_capsObjects.ContainsKey(circuitCode))
112 { 112 {
113 Caps oldCaps = m_capsObjects[agentId]; 113 Caps oldCaps = m_capsObjects[circuitCode];
114 114
115 m_log.DebugFormat( 115 m_log.DebugFormat(
116 "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", 116 "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ",
@@ -125,12 +125,12 @@ namespace OpenSim.Region.CoreModules.Framework
125 (MainServer.Instance == null) ? 0: MainServer.Instance.Port, 125 (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
126 capsObjectPath, agentId, m_scene.RegionInfo.RegionName); 126 capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
127 127
128 m_capsObjects[agentId] = caps; 128 m_capsObjects[circuitCode] = caps;
129 129
130 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); 130 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
131 } 131 }
132 132
133 public void RemoveCaps(UUID agentId) 133 public void RemoveCaps(UUID agentId, uint circuitCode)
134 { 134 {
135 if (childrenSeeds.ContainsKey(agentId)) 135 if (childrenSeeds.ContainsKey(agentId))
136 { 136 {
@@ -139,11 +139,11 @@ namespace OpenSim.Region.CoreModules.Framework
139 139
140 lock (m_capsObjects) 140 lock (m_capsObjects)
141 { 141 {
142 if (m_capsObjects.ContainsKey(agentId)) 142 if (m_capsObjects.ContainsKey(circuitCode))
143 { 143 {
144 m_capsObjects[agentId].DeregisterHandlers(); 144 m_capsObjects[circuitCode].DeregisterHandlers();
145 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]); 145 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[circuitCode]);
146 m_capsObjects.Remove(agentId); 146 m_capsObjects.Remove(circuitCode);
147 } 147 }
148 else 148 else
149 { 149 {
@@ -154,19 +154,30 @@ namespace OpenSim.Region.CoreModules.Framework
154 } 154 }
155 } 155 }
156 156
157 public Caps GetCapsForUser(UUID agentId) 157 public Caps GetCapsForUser(uint circuitCode)
158 { 158 {
159 lock (m_capsObjects) 159 lock (m_capsObjects)
160 { 160 {
161 if (m_capsObjects.ContainsKey(agentId)) 161 if (m_capsObjects.ContainsKey(circuitCode))
162 { 162 {
163 return m_capsObjects[agentId]; 163 return m_capsObjects[circuitCode];
164 } 164 }
165 } 165 }
166 166
167 return null; 167 return null;
168 } 168 }
169 169
170 public void ActivateCaps(uint circuitCode)
171 {
172 lock (m_capsObjects)
173 {
174 if (m_capsObjects.ContainsKey(circuitCode))
175 {
176 m_capsObjects[circuitCode].Activate();
177 }
178 }
179 }
180
170 public void SetAgentCapsSeeds(AgentCircuitData agent) 181 public void SetAgentCapsSeeds(AgentCircuitData agent)
171 { 182 {
172 capsPaths[agent.AgentID] = agent.CapsPath; 183 capsPaths[agent.AgentID] = agent.CapsPath;
@@ -237,9 +248,9 @@ namespace OpenSim.Region.CoreModules.Framework
237 StringBuilder caps = new StringBuilder(); 248 StringBuilder caps = new StringBuilder();
238 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); 249 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
239 250
240 foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects) 251 foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
241 { 252 {
242 caps.AppendFormat("** User {0}:\n", kvp.Key); 253 caps.AppendFormat("** Circuit {0}:\n", kvp.Key);
243 254
244 for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false).GetEnumerator(); kvp2.MoveNext(); ) 255 for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false).GetEnumerator(); kvp2.MoveNext(); )
245 { 256 {
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 cb09047..b70aeb7 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Framework.Capabilities; 34using OpenSim.Framework.Capabilities;
35using OpenSim.Framework.Client; 35using OpenSim.Framework.Client;
36using OpenSim.Framework.Monitoring;
36using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
38using OpenSim.Region.Physics.Manager; 39using OpenSim.Region.Physics.Manager;
@@ -66,6 +67,42 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
66 /// </summary> 67 /// </summary>
67 public bool WaitForAgentArrivedAtDestination { get; set; } 68 public bool WaitForAgentArrivedAtDestination { get; set; }
68 69
70 /// <summary>
71 /// If true then we ask the viewer to disable teleport cancellation and ignore teleport requests.
72 /// </summary>
73 /// <remarks>
74 /// This is useful in situations where teleport is very likely to always succeed and we want to avoid a
75 /// situation where avatars can be come 'stuck' due to a failed teleport cancellation. Unfortunately, the
76 /// nature of the teleport protocol makes it extremely difficult (maybe impossible) to make teleport
77 /// cancellation consistently suceed.
78 /// </remarks>
79 public bool DisableInterRegionTeleportCancellation { get; set; }
80
81 /// <summary>
82 /// Number of times inter-region teleport was attempted.
83 /// </summary>
84 private Stat m_interRegionTeleportAttempts;
85
86 /// <summary>
87 /// Number of times inter-region teleport was aborted (due to simultaneous client logout).
88 /// </summary>
89 private Stat m_interRegionTeleportAborts;
90
91 /// <summary>
92 /// Number of times inter-region teleport was successfully cancelled by the client.
93 /// </summary>
94 private Stat m_interRegionTeleportCancels;
95
96 /// <summary>
97 /// Number of times inter-region teleport failed due to server/client/network problems (e.g. viewer failed to
98 /// connect with destination region).
99 /// </summary>
100 /// <remarks>
101 /// This is not necessarily a problem for this simulator - in open-grid/hg conditions, viewer connectivity to
102 /// destination simulator is unknown.
103 /// </remarks>
104 private Stat m_interRegionTeleportFailures;
105
69 protected bool m_Enabled = false; 106 protected bool m_Enabled = false;
70 107
71 public Scene Scene { get; private set; } 108 public Scene Scene { get; private set; }
@@ -80,6 +117,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
80 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); 117 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
81 118
82 private IEventQueue m_eqModule; 119 private IEventQueue m_eqModule;
120 private IRegionCombinerModule m_regionCombinerModule;
83 121
84 #region ISharedRegionModule 122 #region ISharedRegionModule
85 123
@@ -116,6 +154,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
116 IConfig transferConfig = source.Configs["EntityTransfer"]; 154 IConfig transferConfig = source.Configs["EntityTransfer"];
117 if (transferConfig != null) 155 if (transferConfig != null)
118 { 156 {
157 DisableInterRegionTeleportCancellation
158 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false);
159
119 WaitForAgentArrivedAtDestination 160 WaitForAgentArrivedAtDestination
120 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); 161 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault);
121 162
@@ -142,6 +183,60 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
142 183
143 Scene = scene; 184 Scene = scene;
144 185
186 m_interRegionTeleportAttempts =
187 new Stat(
188 "InterRegionTeleportAttempts",
189 "Number of inter-region teleports attempted.",
190 "This does not count attempts which failed due to pre-conditions (e.g. target simulator refused access).\n"
191 + "You can get successfully teleports by subtracting aborts, cancels and teleport failures from this figure.",
192 "",
193 "entitytransfer",
194 Scene.Name,
195 StatType.Push,
196 null,
197 StatVerbosity.Debug);
198
199 m_interRegionTeleportAborts =
200 new Stat(
201 "InterRegionTeleportAborts",
202 "Number of inter-region teleports aborted due to client actions.",
203 "The chief action is simultaneous logout whilst teleporting.",
204 "",
205 "entitytransfer",
206 Scene.Name,
207 StatType.Push,
208 null,
209 StatVerbosity.Debug);
210
211 m_interRegionTeleportCancels =
212 new Stat(
213 "InterRegionTeleportCancels",
214 "Number of inter-region teleports cancelled by the client.",
215 null,
216 "",
217 "entitytransfer",
218 Scene.Name,
219 StatType.Push,
220 null,
221 StatVerbosity.Debug);
222
223 m_interRegionTeleportFailures =
224 new Stat(
225 "InterRegionTeleportFailures",
226 "Number of inter-region teleports that failed due to server/client/network issues.",
227 "This number may not be very helpful in open-grid/hg situations as the network connectivity/quality of destinations is uncontrollable.",
228 "",
229 "entitytransfer",
230 Scene.Name,
231 StatType.Push,
232 null,
233 StatVerbosity.Debug);
234
235 StatsManager.RegisterStat(m_interRegionTeleportAttempts);
236 StatsManager.RegisterStat(m_interRegionTeleportAborts);
237 StatsManager.RegisterStat(m_interRegionTeleportCancels);
238 StatsManager.RegisterStat(m_interRegionTeleportFailures);
239
145 scene.RegisterModuleInterface<IEntityTransferModule>(this); 240 scene.RegisterModuleInterface<IEntityTransferModule>(this);
146 scene.EventManager.OnNewClient += OnNewClient; 241 scene.EventManager.OnNewClient += OnNewClient;
147 } 242 }
@@ -150,12 +245,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
150 { 245 {
151 client.OnTeleportHomeRequest += TriggerTeleportHome; 246 client.OnTeleportHomeRequest += TriggerTeleportHome;
152 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 247 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
153 client.OnTeleportCancel += TeleportCancel; 248
249 if (!DisableInterRegionTeleportCancellation)
250 client.OnTeleportCancel += OnClientCancelTeleport;
251
252 client.OnConnectionClosed += OnConnectionClosed;
154 } 253 }
155 254
156 public virtual void Close() {} 255 public virtual void Close() {}
157 256
158 public virtual void RemoveRegion(Scene scene) {} 257 public virtual void RemoveRegion(Scene scene)
258 {
259 if (m_Enabled)
260 {
261 StatsManager.DeregisterStat(m_interRegionTeleportAttempts);
262 StatsManager.DeregisterStat(m_interRegionTeleportAborts);
263 StatsManager.DeregisterStat(m_interRegionTeleportCancels);
264 StatsManager.DeregisterStat(m_interRegionTeleportFailures);
265 }
266 }
159 267
160 public virtual void RegionLoaded(Scene scene) 268 public virtual void RegionLoaded(Scene scene)
161 { 269 {
@@ -163,12 +271,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
163 return; 271 return;
164 272
165 m_eqModule = Scene.RequestModuleInterface<IEventQueue>(); 273 m_eqModule = Scene.RequestModuleInterface<IEventQueue>();
274 m_regionCombinerModule = Scene.RequestModuleInterface<IRegionCombinerModule>();
166 } 275 }
167 276
168 #endregion 277 #endregion
169 278
170 #region Agent Teleports 279 #region Agent Teleports
171 280
281 private void OnConnectionClosed(IClientAPI client)
282 {
283 if (client.IsLoggingOut)
284 {
285 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
286
287 m_log.DebugFormat(
288 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
289 client.Name, Scene.Name);
290 }
291 }
292
293 private void OnClientCancelTeleport(IClientAPI client)
294 {
295 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling);
296
297 m_log.DebugFormat(
298 "[ENTITY TRANSFER MODULE]: Received teleport cancel request from {0} in {1}", client.Name, Scene.Name);
299 }
300
172 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) 301 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags)
173 { 302 {
174 if (sp.Scene.Permissions.IsGridGod(sp.UUID)) 303 if (sp.Scene.Permissions.IsGridGod(sp.UUID))
@@ -180,13 +309,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
180 if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) 309 if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
181 return; 310 return;
182 311
183 // Reset animations; the viewer does that in teleports.
184 sp.Animator.ResetAnimations();
185
186 string destinationRegionName = "(not found)"; 312 string destinationRegionName = "(not found)";
187 313
314 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection
315 // of whether the destination region completes the teleport.
316 if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
317 {
318 m_log.DebugFormat(
319 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.",
320 sp.Name, sp.UUID, position, regionHandle);
321
322 return;
323 }
324
188 try 325 try
189 { 326 {
327 // Reset animations; the viewer does that in teleports.
328 sp.Animator.ResetAnimations();
329
190 if (regionHandle == sp.Scene.RegionInfo.RegionHandle) 330 if (regionHandle == sp.Scene.RegionInfo.RegionHandle)
191 { 331 {
192 destinationRegionName = sp.Scene.RegionInfo.RegionName; 332 destinationRegionName = sp.Scene.RegionInfo.RegionName;
@@ -195,12 +335,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
195 } 335 }
196 else // Another region possibly in another simulator 336 else // Another region possibly in another simulator
197 { 337 {
198 GridRegion finalDestination; 338 GridRegion finalDestination = null;
199 TeleportAgentToDifferentRegion( 339 try
200 sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); 340 {
201 341 TeleportAgentToDifferentRegion(
202 if (finalDestination != null) 342 sp, regionHandle, position, lookAt, teleportFlags, out finalDestination);
203 destinationRegionName = finalDestination.RegionName; 343 }
344 finally
345 {
346 if (finalDestination != null)
347 destinationRegionName = finalDestination.RegionName;
348 }
204 } 349 }
205 } 350 }
206 catch (Exception e) 351 catch (Exception e)
@@ -210,11 +355,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
210 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, 355 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName,
211 e.Message, e.StackTrace); 356 e.Message, e.StackTrace);
212 357
213 // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail.
214 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
215
216 sp.ControllingClient.SendTeleportFailed("Internal error"); 358 sp.ControllingClient.SendTeleportFailed("Internal error");
217 } 359 }
360 finally
361 {
362 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
363 }
218 } 364 }
219 365
220 /// <summary> 366 /// <summary>
@@ -230,23 +376,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
230 "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", 376 "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}",
231 sp.Name, position, sp.Scene.RegionInfo.RegionName); 377 sp.Name, position, sp.Scene.RegionInfo.RegionName);
232 378
233 if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
234 {
235 m_log.DebugFormat(
236 "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.",
237 sp.Name, sp.UUID, position);
238
239 return;
240 }
241
242 // Teleport within the same region 379 // Teleport within the same region
243 if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) 380 if (IsOutsideRegion(sp.Scene, position) || position.Z < 0)
244 { 381 {
245 Vector3 emergencyPos = new Vector3(128, 128, 128); 382 Vector3 emergencyPos = new Vector3(128, 128, 128);
246 383
247 m_log.WarnFormat( 384 m_log.WarnFormat(
248 "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", 385 "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2} in {3}. Substituting {4}",
249 position, sp.Name, sp.UUID, emergencyPos); 386 position, sp.Name, sp.UUID, Scene.Name, emergencyPos);
250 387
251 position = emergencyPos; 388 position = emergencyPos;
252 } 389 }
@@ -287,7 +424,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
287 } 424 }
288 425
289 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 426 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
290 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
291 } 427 }
292 428
293 /// <summary> 429 /// <summary>
@@ -341,7 +477,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
341 // 477 //
342 // This is it 478 // This is it
343 // 479 //
344 DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags); 480 DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
345 // 481 //
346 // 482 //
347 // 483 //
@@ -396,27 +532,54 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
396 && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; 532 && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
397 } 533 }
398 534
535 /// <summary>
536 /// Wraps DoTeleportInternal() and manages the transfer state.
537 /// </summary>
399 public void DoTeleport( 538 public void DoTeleport(
400 ScenePresence sp, GridRegion reg, GridRegion finalDestination, 539 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
401 Vector3 position, Vector3 lookAt, uint teleportFlags) 540 Vector3 position, Vector3 lookAt, uint teleportFlags)
402 { 541 {
403 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection 542 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection
404 // of whether the destination region completes the teleport. 543 // of whether the destination region completes the teleport.
405 m_entityTransferStateMachine.SetInTransit(sp.UUID); 544 if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
406// if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) 545 {
407// { 546 m_log.DebugFormat(
408// m_log.DebugFormat( 547 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.",
409// "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", 548 sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
410// sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
411//
412// return;
413// }
414 549
415 if (reg == null || finalDestination == null) 550 return;
551 }
552
553 try
554 {
555 DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
556 }
557 catch (Exception e)
558 {
559 m_log.ErrorFormat(
560 "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}",
561 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, finalDestination.RegionName,
562 e.Message, e.StackTrace);
563
564 sp.ControllingClient.SendTeleportFailed("Internal error");
565 }
566 finally
416 { 567 {
417 sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
418 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 568 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
569 }
570 }
419 571
572 /// <summary>
573 /// Teleports the agent to another region.
574 /// This method doesn't manage the transfer state; the caller must do that.
575 /// </summary>
576 private void DoTeleportInternal(
577 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
578 Vector3 position, Vector3 lookAt, uint teleportFlags)
579 {
580 if (reg == null || finalDestination == null)
581 {
582 sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
420 return; 583 return;
421 } 584 }
422 585
@@ -436,8 +599,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
436 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, 599 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
437 MaxTransferDistance)); 600 MaxTransferDistance));
438 601
439 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
440
441 return; 602 return;
442 } 603 }
443 604
@@ -455,7 +616,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
455 if (endPoint == null || endPoint.Address == null) 616 if (endPoint == null || endPoint.Address == null)
456 { 617 {
457 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 618 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
458 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
459 619
460 return; 620 return;
461 } 621 }
@@ -465,19 +625,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
465 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", 625 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
466 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); 626 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
467 627
468// if (!sp.ValidateAttachments())
469// {
470// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
471// return;
472// }
473
474 string reason; 628 string reason;
475 string version; 629 string version;
476 if (!Scene.SimulationService.QueryAccess( 630 if (!Scene.SimulationService.QueryAccess(
477 finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) 631 finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason))
478 { 632 {
479 sp.ControllingClient.SendTeleportFailed(reason); 633 sp.ControllingClient.SendTeleportFailed(reason);
480 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
481 634
482 m_log.DebugFormat( 635 m_log.DebugFormat(
483 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", 636 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}",
@@ -486,6 +639,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
486 return; 639 return;
487 } 640 }
488 641
642 // Before this point, teleport 'failure' is due to checkable pre-conditions such as whether the target
643 // simulator can be found and is explicitly prepared to allow access. Therefore, we will not count these
644 // as server attempts.
645 m_interRegionTeleportAttempts.Value++;
646
489 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); 647 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version);
490 648
491 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from 649 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
@@ -495,6 +653,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
495 else if (sp.Flying) 653 else if (sp.Flying)
496 teleportFlags |= (uint)TeleportFlags.IsFlying; 654 teleportFlags |= (uint)TeleportFlags.IsFlying;
497 655
656 if (DisableInterRegionTeleportCancellation)
657 teleportFlags |= (uint)TeleportFlags.DisableCancel;
658
498 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to 659 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
499 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). 660 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
500 sp.ControllingClient.SendTeleportStart(teleportFlags); 661 sp.ControllingClient.SendTeleportStart(teleportFlags);
@@ -531,11 +692,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
531 } 692 }
532 693
533 // Let's create an agent there if one doesn't exist yet. 694 // Let's create an agent there if one doesn't exist yet.
695 // NOTE: logout will always be false for a non-HG teleport.
534 bool logout = false; 696 bool logout = false;
535 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) 697 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
536 { 698 {
699 m_interRegionTeleportFailures.Value++;
700
537 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); 701 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
538 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
539 702
540 m_log.DebugFormat( 703 m_log.DebugFormat(
541 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", 704 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
@@ -544,6 +707,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
544 return; 707 return;
545 } 708 }
546 709
710 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
711 {
712 m_interRegionTeleportCancels.Value++;
713
714 m_log.DebugFormat(
715 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
716 sp.Name, finalDestination.RegionName, sp.Scene.Name);
717
718 return;
719 }
720 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
721 {
722 m_interRegionTeleportAborts.Value++;
723
724 m_log.DebugFormat(
725 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
726 sp.Name, finalDestination.RegionName, sp.Scene.Name);
727
728 return;
729 }
730
547 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 731 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
548 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 732 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
549 733
@@ -553,6 +737,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
553 IClientIPEndpoint ipepClient; 737 IClientIPEndpoint ipepClient;
554 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 738 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
555 { 739 {
740 m_log.DebugFormat(
741 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}",
742 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
743
556 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); 744 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
557 #region IP Translation for NAT 745 #region IP Translation for NAT
558 // Uses ipepClient above 746 // Uses ipepClient above
@@ -565,11 +753,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
565 753
566 if (m_eqModule != null) 754 if (m_eqModule != null)
567 { 755 {
756 // The EnableSimulator message makes the client establish a connection with the destination
757 // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the
758 // correct circuit code.
568 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); 759 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID);
569 760
570 // ES makes the client send a UseCircuitCode message to the destination, 761 // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination
571 // which triggers a bunch of things there. 762 // simulator to confirm that it has established communication with the viewer.
572 // So let's wait
573 Thread.Sleep(200); 763 Thread.Sleep(200);
574 764
575 // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears 765 // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears
@@ -580,6 +770,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
580 } 770 }
581 else 771 else
582 { 772 {
773 // XXX: This is a little misleading since we're information the client of its avatar destination,
774 // which may or may not be a neighbour region of the source region. This path is probably little
775 // used anyway (with EQ being the one used). But it is currently being used for test code.
583 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); 776 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
584 } 777 }
585 } 778 }
@@ -597,23 +790,66 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
597 790
598 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); 791 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
599 792
793 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
794 // establish th econnection to the destination which makes it return true.
795 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
796 {
797 m_interRegionTeleportAborts.Value++;
798
799 m_log.DebugFormat(
800 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
801 sp.Name, finalDestination.RegionName, sp.Scene.Name);
802
803 return;
804 }
805
806 // A common teleport failure occurs when we can send CreateAgent to the
807 // destination region but the viewer cannot establish the connection (e.g. due to network issues between
808 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
809 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
600 if (!UpdateAgent(reg, finalDestination, agent, sp)) 810 if (!UpdateAgent(reg, finalDestination, agent, sp))
601 { 811 {
602 // Region doesn't take it 812 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
813 {
814 m_interRegionTeleportAborts.Value++;
815
816 m_log.DebugFormat(
817 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
818 sp.Name, finalDestination.RegionName, sp.Scene.Name);
819
820 return;
821 }
822
603 m_log.WarnFormat( 823 m_log.WarnFormat(
604 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", 824 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
605 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 825 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
606 826
607 Fail(sp, finalDestination, logout); 827 Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established.");
608 return; 828 return;
609 } 829 }
610 830
611 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); 831 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
832 {
833 m_interRegionTeleportCancels.Value++;
834
835 m_log.DebugFormat(
836 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
837 sp.Name, finalDestination.RegionName, sp.Scene.Name);
838
839 CleanupFailedInterRegionTeleport(sp, finalDestination);
840
841 return;
842 }
612 843
613 m_log.DebugFormat( 844 m_log.DebugFormat(
614 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", 845 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
615 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); 846 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
616 847
848 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
849 // where that neighbour simulator could otherwise request a child agent create on the source which then
850 // closes our existing agent which is still signalled as root.
851 sp.IsChildAgent = true;
852
617 if (m_eqModule != null) 853 if (m_eqModule != null)
618 { 854 {
619 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); 855 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID);
@@ -624,19 +860,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
624 teleportFlags, capsPath); 860 teleportFlags, capsPath);
625 } 861 }
626 862
627 // Let's set this to true tentatively. This does not trigger OnChildAgent
628 sp.IsChildAgent = true;
629
630 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which 863 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
631 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation 864 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
632 // that the client contacted the destination before we close things here. 865 // that the client contacted the destination before we close things here.
633 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) 866 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID))
634 { 867 {
868 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
869 {
870 m_interRegionTeleportAborts.Value++;
871
872 m_log.DebugFormat(
873 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
874 sp.Name, finalDestination.RegionName, sp.Scene.Name);
875
876 return;
877 }
878
635 m_log.WarnFormat( 879 m_log.WarnFormat(
636 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", 880 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
637 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 881 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
638 882
639 Fail(sp, finalDestination, logout); 883 Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion.");
884
640 return; 885 return;
641 } 886 }
642 887
@@ -659,8 +904,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
659 // Now let's make it officially a child agent 904 // Now let's make it officially a child agent
660 sp.MakeChildAgent(); 905 sp.MakeChildAgent();
661 906
662// sp.Scene.CleanDroppedAttachments();
663
664 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 907 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
665 908
666 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 909 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
@@ -680,27 +923,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
680 // now we have a child agent in this region. 923 // now we have a child agent in this region.
681 sp.Reset(); 924 sp.Reset();
682 } 925 }
683
684 // Commented pending deletion since this method no longer appears to do anything at all
685// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
686// if (sp.Scene.NeedSceneCacheClear(sp.UUID))
687// {
688// m_log.DebugFormat(
689// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
690// sp.UUID);
691// }
692
693 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
694 } 926 }
695 927
696 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) 928 /// <summary>
929 /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation.
930 /// </summary>
931 /// <remarks>
932 /// All operations here must be idempotent so that we can call this method at any point in the teleport process
933 /// up until we send the TeleportFinish event quene event to the viewer.
934 /// <remarks>
935 /// <param name='sp'> </param>
936 /// <param name='finalDestination'></param>
937 protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
697 { 938 {
698 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 939 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
699 940
700 // Client never contacted destination. Let's restore everything back
701 sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
702
703 // Fail. Reset it back
704 sp.IsChildAgent = false; 941 sp.IsChildAgent = false;
705 ReInstantiateScripts(sp); 942 ReInstantiateScripts(sp);
706 943
@@ -708,10 +945,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
708 945
709 // Finally, kill the agent we just created at the destination. 946 // Finally, kill the agent we just created at the destination.
710 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); 947 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID);
948 }
711 949
712 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); 950 /// <summary>
951 /// Signal that the inter-region teleport failed and perform cleanup.
952 /// </summary>
953 /// <param name='sp'></param>
954 /// <param name='finalDestination'></param>
955 /// <param name='logout'></param>
956 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
957 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason)
958 {
959 CleanupFailedInterRegionTeleport(sp, finalDestination);
960
961 m_interRegionTeleportFailures.Value++;
713 962
714 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 963 sp.ControllingClient.SendTeleportFailed(
964 string.Format(
965 "Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason));
966
967 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
715 } 968 }
716 969
717 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) 970 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
@@ -762,7 +1015,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
762 1015
763 protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) 1016 protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY)
764 { 1017 {
765 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); 1018 if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
1019 {
1020 Vector2 swCorner, neCorner;
1021 GetMegaregionViewRange(out swCorner, out neCorner);
1022
1023 m_log.DebugFormat(
1024 "[ENTITY TRANSFER MODULE]: Megaregion view of {0} is from {1} to {2} with new agent check for {3},{4}",
1025 Scene.Name, swCorner, neCorner, newRegionX, newRegionY);
1026
1027 return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y);
1028 }
1029 else
1030 {
1031 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY);
1032 }
766 } 1033 }
767 1034
768 protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) 1035 protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg)
@@ -866,6 +1133,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
866 { 1133 {
867 version = String.Empty; 1134 version = String.Empty;
868 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1135 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1136
1137// m_log.DebugFormat(
1138// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1139
869 uint neighbourx = scene.RegionInfo.RegionLocX; 1140 uint neighbourx = scene.RegionInfo.RegionLocX;
870 uint neighboury = scene.RegionInfo.RegionLocY; 1141 uint neighboury = scene.RegionInfo.RegionLocY;
871 const float boundaryDistance = 1.7f; 1142 const float boundaryDistance = 1.7f;
@@ -995,11 +1266,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
995 return neighbourRegion; 1266 return neighbourRegion;
996 } 1267 }
997 1268
998 private void TeleportCancel(IClientAPI remoteClient)
999 {
1000 m_entityTransferStateMachine.ResetFromTransit(remoteClient.AgentId);
1001 }
1002
1003 public bool Cross(ScenePresence agent, bool isFlying) 1269 public bool Cross(ScenePresence agent, bool isFlying)
1004 { 1270 {
1005 uint x; 1271 uint x;
@@ -1023,16 +1289,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1023 } 1289 }
1024 1290
1025 1291
1026 public delegate void InformClientToInitateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, 1292 public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY,
1027 Vector3 position, 1293 Vector3 position,
1028 Scene initiatingScene); 1294 Scene initiatingScene);
1029 1295
1030 private void InformClientToInitateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) 1296 private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene)
1031 { 1297 {
1032 1298
1033 // This assumes that we know what our neighbours are. 1299 // This assumes that we know what our neighbours are.
1034 1300
1035 InformClientToInitateTeleportToLocationDelegate d = InformClientToInitiateTeleportToLocationAsync; 1301 InformClientToInitiateTeleportToLocationDelegate d = InformClientToInitiateTeleportToLocationAsync;
1036 d.BeginInvoke(agent, regionX, regionY, position, initiatingScene, 1302 d.BeginInvoke(agent, regionX, regionY, position, initiatingScene,
1037 InformClientToInitiateTeleportToLocationCompleted, 1303 InformClientToInitiateTeleportToLocationCompleted,
1038 d); 1304 d);
@@ -1042,7 +1308,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1042 Scene initiatingScene) 1308 Scene initiatingScene)
1043 { 1309 {
1044 Thread.Sleep(10000); 1310 Thread.Sleep(10000);
1045 1311
1312 m_log.DebugFormat(
1313 "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}",
1314 agent.Name, regionX, regionY, position, initiatingScene.Name);
1315
1316 agent.Scene.RequestTeleportLocation(
1317 agent.ControllingClient,
1318 Utils.UIntsToLong(regionX * (uint)Constants.RegionSize, regionY * (uint)Constants.RegionSize),
1319 position,
1320 agent.Lookat,
1321 (uint)Constants.TeleportFlags.ViaLocation);
1322
1323 /*
1046 IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>(); 1324 IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>();
1047 if (im != null) 1325 if (im != null)
1048 { 1326 {
@@ -1077,12 +1355,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1077 }); 1355 });
1078 1356
1079 } 1357 }
1358 */
1080 } 1359 }
1081 1360
1082 private void InformClientToInitiateTeleportToLocationCompleted(IAsyncResult iar) 1361 private void InformClientToInitiateTeleportToLocationCompleted(IAsyncResult iar)
1083 { 1362 {
1084 InformClientToInitateTeleportToLocationDelegate icon = 1363 InformClientToInitiateTeleportToLocationDelegate icon =
1085 (InformClientToInitateTeleportToLocationDelegate)iar.AsyncState; 1364 (InformClientToInitiateTeleportToLocationDelegate)iar.AsyncState;
1086 icon.EndInvoke(iar); 1365 icon.EndInvoke(iar);
1087 } 1366 }
1088 1367
@@ -1107,10 +1386,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1107 bool isFlying, string version) 1386 bool isFlying, string version)
1108 { 1387 {
1109 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) 1388 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1389 {
1390 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1110 return agent; 1391 return agent;
1392 }
1111 1393
1112 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) 1394 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1395 {
1396 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1113 return agent; 1397 return agent;
1398 }
1114 1399
1115 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version); 1400 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1116 return agent; 1401 return agent;
@@ -1137,9 +1422,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1137 // region doesn't take it 1422 // region doesn't take it
1138 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1423 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1139 1424
1425 m_log.WarnFormat(
1426 "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.",
1427 neighbourRegion.RegionName, agent.Name);
1428
1140 ReInstantiateScripts(agent); 1429 ReInstantiateScripts(agent);
1141 agent.AddToPhysicalScene(isFlying); 1430 agent.AddToPhysicalScene(isFlying);
1142 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1143 1431
1144 return false; 1432 return false;
1145 } 1433 }
@@ -1576,6 +1864,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1576 } 1864 }
1577 1865
1578 /// <summary> 1866 /// <summary>
1867 /// Gets the range considered in view of this megaregion (assuming this is a megaregion).
1868 /// </summary>
1869 /// <remarks>Expressed in 256m units</remarks>
1870 /// <param name='swCorner'></param>
1871 /// <param name='neCorner'></param>
1872 private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner)
1873 {
1874 Border[] northBorders = Scene.NorthBorders.ToArray();
1875 Border[] eastBorders = Scene.EastBorders.ToArray();
1876
1877 Vector2 extent = Vector2.Zero;
1878 for (int i = 0; i < eastBorders.Length; i++)
1879 {
1880 extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X;
1881 }
1882 for (int i = 0; i < northBorders.Length; i++)
1883 {
1884 extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y;
1885 }
1886
1887 // Loss of fraction on purpose
1888 extent.X = ((int)extent.X / (int)Constants.RegionSize);
1889 extent.Y = ((int)extent.Y / (int)Constants.RegionSize);
1890
1891 swCorner.X = Scene.RegionInfo.RegionLocX - 1;
1892 swCorner.Y = Scene.RegionInfo.RegionLocY - 1;
1893 neCorner.X = Scene.RegionInfo.RegionLocX + extent.X;
1894 neCorner.Y = Scene.RegionInfo.RegionLocY + extent.Y;
1895 }
1896
1897 /// <summary>
1579 /// Return the list of regions that are considered to be neighbours to the given scene. 1898 /// Return the list of regions that are considered to be neighbours to the given scene.
1580 /// </summary> 1899 /// </summary>
1581 /// <param name="pScene"></param> 1900 /// <param name="pScene"></param>
@@ -1587,15 +1906,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1587 Scene pScene = avatar.Scene; 1906 Scene pScene = avatar.Scene;
1588 RegionInfo m_regionInfo = pScene.RegionInfo; 1907 RegionInfo m_regionInfo = pScene.RegionInfo;
1589 1908
1590 Border[] northBorders = pScene.NorthBorders.ToArray();
1591 Border[] southBorders = pScene.SouthBorders.ToArray();
1592 Border[] eastBorders = pScene.EastBorders.ToArray();
1593 Border[] westBorders = pScene.WestBorders.ToArray();
1594
1595 // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't 1909 // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't
1596 // clear what should be done with a "far view" given that megaregions already extended the 1910 // clear what should be done with a "far view" given that megaregions already extended the
1597 // view to include everything in the megaregion 1911 // view to include everything in the megaregion
1598 if (northBorders.Length <= 1 && southBorders.Length <= 1 && eastBorders.Length <= 1 && westBorders.Length <= 1) 1912 if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
1599 { 1913 {
1600 int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance; 1914 int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance;
1601 1915
@@ -1613,27 +1927,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1613 } 1927 }
1614 else 1928 else
1615 { 1929 {
1616 Vector2 extent = Vector2.Zero; 1930 Vector2 swCorner, neCorner;
1617 for (int i = 0; i < eastBorders.Length; i++) 1931 GetMegaregionViewRange(out swCorner, out neCorner);
1618 {
1619 extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X;
1620 }
1621 for (int i = 0; i < northBorders.Length; i++)
1622 {
1623 extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y;
1624 }
1625
1626 // Loss of fraction on purpose
1627 extent.X = ((int)extent.X / (int)Constants.RegionSize) + 1;
1628 extent.Y = ((int)extent.Y / (int)Constants.RegionSize) + 1;
1629
1630 int startX = (int)(pRegionLocX - 1) * (int)Constants.RegionSize;
1631 int startY = (int)(pRegionLocY - 1) * (int)Constants.RegionSize;
1632 1932
1633 int endX = ((int)pRegionLocX + (int)extent.X) * (int)Constants.RegionSize; 1933 List<GridRegion> neighbours
1634 int endY = ((int)pRegionLocY + (int)extent.Y) * (int)Constants.RegionSize; 1934 = pScene.GridService.GetRegionRange(
1935 m_regionInfo.ScopeID,
1936 (int)swCorner.X * (int)Constants.RegionSize,
1937 (int)neCorner.X * (int)Constants.RegionSize,
1938 (int)swCorner.Y * (int)Constants.RegionSize,
1939 (int)neCorner.Y * (int)Constants.RegionSize);
1635 1940
1636 List<GridRegion> neighbours = pScene.GridService.GetRegionRange(m_regionInfo.ScopeID, startX, endX, startY, endY);
1637 neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); 1941 neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; });
1638 1942
1639 return neighbours; 1943 return neighbours;
@@ -2054,7 +2358,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2054 2358
2055 public bool IsInTransit(UUID id) 2359 public bool IsInTransit(UUID id)
2056 { 2360 {
2057 return m_entityTransferStateMachine.IsInTransit(id); 2361 return m_entityTransferStateMachine.GetAgentTransferState(id) != null;
2058 } 2362 }
2059 2363
2060 protected void ReInstantiateScripts(ScenePresence sp) 2364 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..d372c0e 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -199,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
199 199
200 public override void RemoveRegion(Scene scene) 200 public override void RemoveRegion(Scene scene)
201 { 201 {
202 base.AddRegion(scene); 202 base.RemoveRegion(scene);
203 203
204 if (m_Enabled) 204 if (m_Enabled)
205 scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); 205 scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this);
@@ -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/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 6e5a4a5..5aad7f0 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -47,6 +47,7 @@ using OpenMetaverse;
47using log4net; 47using log4net;
48using Nini.Config; 48using Nini.Config;
49using Mono.Addins; 49using Mono.Addins;
50using PermissionMask = OpenSim.Framework.PermissionMask;
50 51
51namespace OpenSim.Region.CoreModules.Framework.InventoryAccess 52namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
52{ 53{
@@ -398,7 +399,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
398 objectGroup.RootPart.NextOwnerMask &= 399 objectGroup.RootPart.NextOwnerMask &=
399 ((uint)PermissionMask.Copy | 400 ((uint)PermissionMask.Copy |
400 (uint)PermissionMask.Transfer | 401 (uint)PermissionMask.Transfer |
401 (uint)PermissionMask.Modify); 402 (uint)PermissionMask.Modify |
403 (uint)PermissionMask.Export);
402 objectGroup.RootPart.NextOwnerMask |= 404 objectGroup.RootPart.NextOwnerMask |=
403 (uint)PermissionMask.Move; 405 (uint)PermissionMask.Move;
404 406
@@ -506,7 +508,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
506 InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions, 508 InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions,
507 IClientAPI remoteClient) 509 IClientAPI remoteClient)
508 { 510 {
509 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; 511 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7;
510 // For the porposes of inventory, an object is modify if the prims 512 // For the porposes of inventory, an object is modify if the prims
511 // are modify. This allows renaming an object that contains no 513 // are modify. This allows renaming an object that contains no
512 // mod items. 514 // mod items.
@@ -555,6 +557,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
555 (uint)PermissionMask.Transfer | 557 (uint)PermissionMask.Transfer |
556 (uint)PermissionMask.Modify | 558 (uint)PermissionMask.Modify |
557 (uint)PermissionMask.Move | 559 (uint)PermissionMask.Move |
560 (uint)PermissionMask.Export |
558 7); // Preserve folded permissions 561 7); // Preserve folded permissions
559 } 562 }
560 563
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/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index ec22146..d07cff4 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -43,6 +43,7 @@ using OpenMetaverse;
43using log4net; 43using log4net;
44using Mono.Addins; 44using Mono.Addins;
45using Nini.Config; 45using Nini.Config;
46using PermissionMask = OpenSim.Framework.PermissionMask;
46 47
47namespace OpenSim.Region.CoreModules.Framework.Library 48namespace OpenSim.Region.CoreModules.Framework.Library
48{ 49{
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/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 0276267..2b13a8b 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -189,6 +189,45 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
189 case (int)HttpRequestConstants.HTTP_VERIFY_CERT: 189 case (int)HttpRequestConstants.HTTP_VERIFY_CERT:
190 htc.HttpVerifyCert = (int.Parse(parms[i + 1]) != 0); 190 htc.HttpVerifyCert = (int.Parse(parms[i + 1]) != 0);
191 break; 191 break;
192
193 case (int)HttpRequestConstants.HTTP_VERBOSE_THROTTLE:
194
195 // TODO implement me
196 break;
197
198 case (int)HttpRequestConstants.HTTP_CUSTOM_HEADER:
199 //Parameters are in pairs and custom header takes
200 //arguments in pairs so adjust for header marker.
201 ++i;
202
203 //Maximum of 8 headers are allowed based on the
204 //Second Life documentation for llHTTPRequest.
205 for (int count = 1; count <= 8; ++count)
206 {
207 //Not enough parameters remaining for a header?
208 if (parms.Length - i < 2)
209 break;
210
211 //Have we reached the end of the list of headers?
212 //End is marked by a string with a single digit.
213 //We already know we have at least one parameter
214 //so it is safe to do this check at top of loop.
215 if (Char.IsDigit(parms[i][0]))
216 break;
217
218 if (htc.HttpCustomHeaders == null)
219 htc.HttpCustomHeaders = new List<string>();
220
221 htc.HttpCustomHeaders.Add(parms[i]);
222 htc.HttpCustomHeaders.Add(parms[i+1]);
223
224 i += 2;
225 }
226 break;
227
228 case (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE:
229 htc.HttpPragmaNoCache = (int.Parse(parms[i + 1]) != 0);
230 break;
192 } 231 }
193 } 232 }
194 } 233 }
@@ -353,9 +392,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
353 // public const int HTTP_METHOD = 0; 392 // public const int HTTP_METHOD = 0;
354 // public const int HTTP_MIMETYPE = 1; 393 // public const int HTTP_MIMETYPE = 1;
355 // public const int HTTP_VERIFY_CERT = 3; 394 // public const int HTTP_VERIFY_CERT = 3;
395 // public const int HTTP_VERBOSE_THROTTLE = 4;
396 // public const int HTTP_CUSTOM_HEADER = 5;
397 // public const int HTTP_PRAGMA_NO_CACHE = 6;
356 private bool _finished; 398 private bool _finished;
357 public bool Finished 399 public bool Finished
358 { 400 {
359 get { return _finished; } 401 get { return _finished; }
360 } 402 }
361 // public int HttpBodyMaxLen = 2048; // not implemented 403 // public int HttpBodyMaxLen = 2048; // not implemented
@@ -367,9 +409,14 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
367 public bool HttpVerifyCert = true; 409 public bool HttpVerifyCert = true;
368 public IWorkItemResult WorkItem = null; 410 public IWorkItemResult WorkItem = null;
369 411
412 //public bool HttpVerboseThrottle = true; // not implemented
413 public List<string> HttpCustomHeaders = null;
414 public bool HttpPragmaNoCache = true;
415 private Thread httpThread;
416
370 // Request info 417 // Request info
371 private UUID _itemID; 418 private UUID _itemID;
372 public UUID ItemID 419 public UUID ItemID
373 { 420 {
374 get { return _itemID; } 421 get { return _itemID; }
375 set { _itemID = value; } 422 set { _itemID = value; }
@@ -385,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
385 public string proxyexcepts; 432 public string proxyexcepts;
386 public string OutboundBody; 433 public string OutboundBody;
387 private UUID _reqID; 434 private UUID _reqID;
388 public UUID ReqID 435 public UUID ReqID
389 { 436 {
390 get { return _reqID; } 437 get { return _reqID; }
391 set { _reqID = value; } 438 set { _reqID = value; }
@@ -434,20 +481,34 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
434 Request.Method = HttpMethod; 481 Request.Method = HttpMethod;
435 Request.ContentType = HttpMIMEType; 482 Request.ContentType = HttpMIMEType;
436 483
437 if(!HttpVerifyCert) 484 if (!HttpVerifyCert)
438 { 485 {
439 // We could hijack Connection Group Name to identify 486 // We could hijack Connection Group Name to identify
440 // a desired security exception. But at the moment we'll use a dummy header instead. 487 // a desired security exception. But at the moment we'll use a dummy header instead.
441 Request.Headers.Add("NoVerifyCert", "true"); 488 Request.Headers.Add("NoVerifyCert", "true");
442 } 489 }
443 if (proxyurl != null && proxyurl.Length > 0) 490// else
491// {
492// Request.ConnectionGroupName="Verify";
493// }
494 if (!HttpPragmaNoCache)
495 {
496 Request.Headers.Add("Pragma", "no-cache");
497 }
498 if (HttpCustomHeaders != null)
444 { 499 {
445 if (proxyexcepts != null && proxyexcepts.Length > 0) 500 for (int i = 0; i < HttpCustomHeaders.Count; i += 2)
501 Request.Headers.Add(HttpCustomHeaders[i],
502 HttpCustomHeaders[i+1]);
503 }
504 if (proxyurl != null && proxyurl.Length > 0)
505 {
506 if (proxyexcepts != null && proxyexcepts.Length > 0)
446 { 507 {
447 string[] elist = proxyexcepts.Split(';'); 508 string[] elist = proxyexcepts.Split(';');
448 Request.Proxy = new WebProxy(proxyurl, true, elist); 509 Request.Proxy = new WebProxy(proxyurl, true, elist);
449 } 510 }
450 else 511 else
451 { 512 {
452 Request.Proxy = new WebProxy(proxyurl, true); 513 Request.Proxy = new WebProxy(proxyurl, true);
453 } 514 }
@@ -460,7 +521,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
460 Request.Headers[entry.Key] = entry.Value; 521 Request.Headers[entry.Key] = entry.Value;
461 522
462 // Encode outbound data 523 // Encode outbound data
463 if (OutboundBody.Length > 0) 524 if (OutboundBody.Length > 0)
464 { 525 {
465 byte[] data = Util.UTF8.GetBytes(OutboundBody); 526 byte[] data = Util.UTF8.GetBytes(OutboundBody);
466 527
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index da59eab..f2922d6 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
50 public string url; 50 public string url;
51 public UUID urlcode; 51 public UUID urlcode;
52 public Dictionary<UUID, RequestData> requests; 52 public Dictionary<UUID, RequestData> requests;
53 public bool isSsl;
53 } 54 }
54 55
55 public class RequestData 56 public class RequestData
@@ -83,20 +84,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
83 private Dictionary<string, UrlData> m_UrlMap = 84 private Dictionary<string, UrlData> m_UrlMap =
84 new Dictionary<string, UrlData>(); 85 new Dictionary<string, UrlData>();
85 86
86 /// <summary> 87 private uint m_HttpsPort = 0;
87 /// Maximum number of external urls that can be set up by this module.
88 /// </summary>
89 private int m_TotalUrls = 15000;
90
91 private uint https_port = 0;
92 private IHttpServer m_HttpServer = null; 88 private IHttpServer m_HttpServer = null;
93 private IHttpServer m_HttpsServer = null; 89 private IHttpServer m_HttpsServer = null;
94 90
95 private string m_ExternalHostNameForLSL = ""; 91 public string ExternalHostNameForLSL { get; private set; }
96 public string ExternalHostNameForLSL 92
97 { 93 /// <summary>
98 get { return m_ExternalHostNameForLSL; } 94 /// The default maximum number of urls
99 } 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; }
100 102
101 public Type ReplaceableInterface 103 public Type ReplaceableInterface
102 { 104 {
@@ -110,17 +112,27 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
110 112
111 public void Initialise(IConfigSource config) 113 public void Initialise(IConfigSource config)
112 { 114 {
113 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); 115 IConfig networkConfig = config.Configs["Network"];
114 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); 116
115 if (ssl_enabled) 117 if (networkConfig != null)
116 { 118 {
117 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);
118 } 125 }
119 126
127 if (ExternalHostNameForLSL == null)
128 ExternalHostNameForLSL = System.Environment.MachineName;
129
120 IConfig llFunctionsConfig = config.Configs["LL-Functions"]; 130 IConfig llFunctionsConfig = config.Configs["LL-Functions"];
121 131
122 if (llFunctionsConfig != null) 132 if (llFunctionsConfig != null)
123 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;
124 } 136 }
125 137
126 public void PostInitialise() 138 public void PostInitialise()
@@ -136,9 +148,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
136 m_HttpServer = MainServer.Instance; 148 m_HttpServer = MainServer.Instance;
137 // 149 //
138 // We can use the https if it is enabled 150 // We can use the https if it is enabled
139 if (https_port > 0) 151 if (m_HttpsPort > 0)
140 { 152 {
141 m_HttpsServer = MainServer.GetHttpServer(https_port); 153 m_HttpsServer = MainServer.GetHttpServer(m_HttpsPort);
142 } 154 }
143 } 155 }
144 156
@@ -171,12 +183,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
171 183
172 lock (m_UrlMap) 184 lock (m_UrlMap)
173 { 185 {
174 if (m_UrlMap.Count >= m_TotalUrls) 186 if (m_UrlMap.Count >= TotalUrls)
175 { 187 {
176 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", "" });
177 return urlcode; 189 return urlcode;
178 } 190 }
179 string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString(); 191 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString();
180 192
181 UrlData urlData = new UrlData(); 193 UrlData urlData = new UrlData();
182 urlData.hostID = host.UUID; 194 urlData.hostID = host.UUID;
@@ -184,6 +196,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
184 urlData.engine = engine; 196 urlData.engine = engine;
185 urlData.url = url; 197 urlData.url = url;
186 urlData.urlcode = urlcode; 198 urlData.urlcode = urlcode;
199 urlData.isSsl = false;
187 urlData.requests = new Dictionary<UUID, RequestData>(); 200 urlData.requests = new Dictionary<UUID, RequestData>();
188 201
189 m_UrlMap[url] = urlData; 202 m_UrlMap[url] = urlData;
@@ -216,12 +229,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
216 229
217 lock (m_UrlMap) 230 lock (m_UrlMap)
218 { 231 {
219 if (m_UrlMap.Count >= m_TotalUrls) 232 if (m_UrlMap.Count >= TotalUrls)
220 { 233 {
221 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", "" });
222 return urlcode; 235 return urlcode;
223 } 236 }
224 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString(); 237 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString();
225 238
226 UrlData urlData = new UrlData(); 239 UrlData urlData = new UrlData();
227 urlData.hostID = host.UUID; 240 urlData.hostID = host.UUID;
@@ -229,6 +242,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
229 urlData.engine = engine; 242 urlData.engine = engine;
230 urlData.url = url; 243 urlData.url = url;
231 urlData.urlcode = urlcode; 244 urlData.urlcode = urlcode;
245 urlData.isSsl = true;
232 urlData.requests = new Dictionary<UUID, RequestData>(); 246 urlData.requests = new Dictionary<UUID, RequestData>();
233 247
234 248
@@ -301,6 +315,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
301 UrlData urlData = m_RequestMap[request]; 315 UrlData urlData = m_RequestMap[request];
302 if (!urlData.requests[request].responseSent) 316 if (!urlData.requests[request].responseSent)
303 { 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
304 urlData.requests[request].responseCode = status; 333 urlData.requests[request].responseCode = status;
305 urlData.requests[request].responseBody = body; 334 urlData.requests[request].responseBody = body;
306 //urlData.requests[request].ev.Set(); 335 //urlData.requests[request].ev.Set();
@@ -336,7 +365,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
336 365
337 public int GetFreeUrls() 366 public int GetFreeUrls()
338 { 367 {
339 return m_TotalUrls - m_UrlMap.Count; 368 lock (m_UrlMap)
369 return TotalUrls - m_UrlMap.Count;
340 } 370 }
341 371
342 public void ScriptRemoved(UUID itemID) 372 public void ScriptRemoved(UUID itemID)
@@ -394,7 +424,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
394 424
395 private void RemoveUrl(UrlData data) 425 private void RemoveUrl(UrlData data)
396 { 426 {
397 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/"); 427 if (data.isSsl)
428 m_HttpsServer.RemoveHTTPHandler("", "/lslhttps/"+data.urlcode.ToString()+"/");
429 else
430 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
398 } 431 }
399 432
400 private Hashtable NoEvents(UUID requestID, UUID sessionID) 433 private Hashtable NoEvents(UUID requestID, UUID sessionID)
@@ -527,7 +560,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
527 { 560 {
528 Hashtable headers = (Hashtable)request["headers"]; 561 Hashtable headers = (Hashtable)request["headers"];
529 562
530// 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() + "/";
531 564
532 int pos1 = uri.IndexOf("/");// /lslhttp 565 int pos1 = uri.IndexOf("/");// /lslhttp
533 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/ 566 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
@@ -543,10 +576,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
543 UrlData url = null; 576 UrlData url = null;
544 string urlkey; 577 string urlkey;
545 if (!is_ssl) 578 if (!is_ssl)
546 urlkey = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 579 urlkey = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
547 //m_UrlMap[]; 580 //m_UrlMap[];
548 else 581 else
549 urlkey = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 582 urlkey = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
550 583
551 if (m_UrlMap.ContainsKey(urlkey)) 584 if (m_UrlMap.ContainsKey(urlkey))
552 { 585 {
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index f6e1d39..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);
@@ -262,6 +262,8 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
262 return "modInvokeR"; 262 return "modInvokeR";
263 else if (sid.ReturnType == typeof(object[])) 263 else if (sid.ReturnType == typeof(object[]))
264 return "modInvokeL"; 264 return "modInvokeL";
265 else if (sid.ReturnType == typeof(void))
266 return "modInvokeN";
265 267
266 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name); 268 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
267 } 269 }
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..a990898 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -44,6 +44,7 @@ using Ionic.Zlib;
44using GZipStream = Ionic.Zlib.GZipStream; 44using GZipStream = Ionic.Zlib.GZipStream;
45using CompressionMode = Ionic.Zlib.CompressionMode; 45using CompressionMode = Ionic.Zlib.CompressionMode;
46using OpenSim.Framework.Serialization.External; 46using OpenSim.Framework.Serialization.External;
47using PermissionMask = OpenSim.Framework.PermissionMask;
47 48
48namespace OpenSim.Region.CoreModules.World.Archiver 49namespace OpenSim.Region.CoreModules.World.Archiver
49{ 50{
@@ -167,7 +168,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
167 } 168 }
168 scenesGroup.CalcSceneLocations(); 169 scenesGroup.CalcSceneLocations();
169 170
170
171 m_archiveWriter = new TarArchiveWriter(m_saveStream); 171 m_archiveWriter = new TarArchiveWriter(m_saveStream);
172 172
173 try 173 try
@@ -216,7 +216,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
216 } 216 }
217 } 217 }
218 218
219
220 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids) 219 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids)
221 { 220 {
222 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName); 221 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName);
@@ -540,7 +539,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
540 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); 539 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
541 } 540 }
542 541
543
544 protected void Save(Scene scene, List<SceneObjectGroup> sceneObjects, string regionDir) 542 protected void Save(Scene scene, List<SceneObjectGroup> sceneObjects, string regionDir)
545 { 543 {
546 if (regionDir != string.Empty) 544 if (regionDir != string.Empty)
@@ -560,8 +558,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
560 foreach (ILandObject lo in landObjects) 558 foreach (ILandObject lo in landObjects)
561 { 559 {
562 LandData landData = lo.LandData; 560 LandData landData = lo.LandData;
563 string landDataPath = String.Format("{0}{1}{2}.xml", 561 string landDataPath
564 regionDir, ArchiveConstants.LANDDATA_PATH, landData.GlobalID.ToString()); 562 = String.Format("{0}{1}", regionDir, ArchiveConstants.CreateOarLandDataPath(landData));
565 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options)); 563 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
566 } 564 }
567 565
@@ -590,21 +588,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
590 } 588 }
591 } 589 }
592 590
593 protected void ReceivedAllAssets( 591 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut)
594 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
595 { 592 {
596 foreach (UUID uuid in assetsNotFoundUuids) 593 string errorMessage;
594
595 if (timedOut)
597 { 596 {
598 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid); 597 errorMessage = "Loading assets timed out";
599 } 598 }
599 else
600 {
601 foreach (UUID uuid in assetsNotFoundUuids)
602 {
603 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid);
604 }
600 605
601 // m_log.InfoFormat( 606 // m_log.InfoFormat(
602 // "[ARCHIVER]: Received {0} of {1} assets requested", 607 // "[ARCHIVER]: Received {0} of {1} assets requested",
603 // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count); 608 // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
604 609
605 CloseArchive(String.Empty); 610 errorMessage = String.Empty;
611 }
612
613 CloseArchive(errorMessage);
606 } 614 }
607
608 615
609 /// <summary> 616 /// <summary>
610 /// Closes the archive and notifies that we're done. 617 /// Closes the archive and notifies that we're done.
@@ -629,6 +636,5 @@ namespace OpenSim.Region.CoreModules.World.Archiver
629 636
630 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage); 637 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage);
631 } 638 }
632
633 } 639 }
634} 640}
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/LightShare/LightShareModule.cs b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
index 6f92ef6..f13d648 100644
--- a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
+++ b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
@@ -198,12 +198,12 @@ namespace OpenSim.Region.CoreModules.World.LightShare
198 if (m_scene.RegionInfo.WindlightSettings.valid) 198 if (m_scene.RegionInfo.WindlightSettings.valid)
199 { 199 {
200 List<byte[]> param = compileWindlightSettings(wl); 200 List<byte[]> param = compileWindlightSettings(wl);
201 client.SendGenericMessage("Windlight", param); 201 client.SendGenericMessage("Windlight", UUID.Random(), param);
202 } 202 }
203 else 203 else
204 { 204 {
205 List<byte[]> param = new List<byte[]>(); 205 List<byte[]> param = new List<byte[]>();
206 client.SendGenericMessage("WindlightReset", param); 206 client.SendGenericMessage("WindlightReset", UUID.Random(), param);
207 } 207 }
208 } 208 }
209 } 209 }
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/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index eb4731c..28daf2f 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -38,6 +38,7 @@ using OpenSim.Region.Framework;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.Framework.Scenes.Serialization; 40using OpenSim.Region.Framework.Scenes.Serialization;
41using PermissionMask = OpenSim.Framework.PermissionMask;
41 42
42namespace OpenSim.Region.CoreModules.World.Objects.BuySell 43namespace OpenSim.Region.CoreModules.World.Objects.BuySell
43{ 44{
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index ab8f143..e434b2e 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,61 @@ 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("Location (relative)", sop.RelativePosition);
601 cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a"));
602 cdl.AddRow("PathBegin", s.PathBegin);
603 cdl.AddRow("PathEnd", s.PathEnd);
604 cdl.AddRow("PathCurve", s.PathCurve);
605 cdl.AddRow("PathRadiusOffset", s.PathRadiusOffset);
606 cdl.AddRow("PathRevolutions", s.PathRevolutions);
607 cdl.AddRow("PathScale", string.Format("<{0},{1}>", s.PathScaleX, s.PathScaleY));
608 cdl.AddRow("PathSkew", string.Format("<{0},{1}>", s.PathShearX, s.PathShearY));
609 cdl.AddRow("FlexiDrag", s.PathSkew);
610 cdl.AddRow("PathTaper", string.Format("<{0},{1}>", s.PathTaperX, s.PathTaperY));
611 cdl.AddRow("PathTwist", s.PathTwist);
612 cdl.AddRow("PathTwistBegin", s.PathTwistBegin);
613 cdl.AddRow("PCode", s.PCode);
614 cdl.AddRow("ProfileBegin", s.ProfileBegin);
615 cdl.AddRow("ProfileEnd", s.ProfileEnd);
616 cdl.AddRow("ProfileHollow", s.ProfileHollow);
617 cdl.AddRow("ProfileShape", s.ProfileShape);
618 cdl.AddRow("ProjectionAmbiance", s.ProjectionAmbiance);
619 cdl.AddRow("ProjectionEntry", s.ProjectionEntry);
620 cdl.AddRow("ProjectionFocus", s.ProjectionFocus);
621 cdl.AddRow("ProjectionFOV", s.ProjectionFOV);
622 cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID);
623 cdl.AddRow("Rotation (Relative)", sop.RotationOffset);
624 cdl.AddRow("Rotation (World)", sop.GetWorldRotation());
625 cdl.AddRow("Scale", s.Scale);
626 cdl.AddRow(
627 "SculptData",
628 string.Format("{0} bytes", s.SculptData != null ? s.SculptData.Length.ToString() : "n/a"));
629 cdl.AddRow("SculptEntry", s.SculptEntry);
630 cdl.AddRow("SculptTexture", s.SculptTexture);
631 cdl.AddRow("SculptType", s.SculptType);
632 cdl.AddRow("State", s.State);
633
634 // TODO, unpack and display texture entries
635 //cdl.AddRow("Textures", string.Format("{0} entries", s.Textures.
636 }
637
580 object itemsOutput; 638 object itemsOutput;
581 if (showFull) 639 if (showFull)
582 { 640 {
@@ -588,7 +646,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
588 itemsOutput = sop.Inventory.Count; 646 itemsOutput = sop.Inventory.Count;
589 } 647 }
590 648
591
592 cdl.AddRow("Items", itemsOutput); 649 cdl.AddRow("Items", itemsOutput);
593 650
594 return sb.Append(cdl.ToString()); 651 return sb.Append(cdl.ToString());
@@ -842,17 +899,17 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
842 899
843 if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) 900 if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
844 { 901 {
845 m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector); 902 m_console.OutputFormat("Error: Start vector '{0}' does not have a valid format", rawConsoleStartVector);
846 endVector = Vector3.Zero; 903 endVector = Vector3.Zero;
847 904
848 return false; 905 return false;
849 } 906 }
850 907
851 string rawConsoleEndVector = rawComponents.Skip(1).Take(1).Single(); 908 string rawConsoleEndVector = rawComponents.Skip(2).Take(1).Single();
852 909
853 if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) 910 if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
854 { 911 {
855 m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector); 912 m_console.OutputFormat("Error: End vector '{0}' does not have a valid format", rawConsoleEndVector);
856 return false; 913 return false;
857 } 914 }
858 915
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index ddaa227..79dd4a0 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -38,6 +38,7 @@ using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
39 39
40using Mono.Addins; 40using Mono.Addins;
41using PermissionMask = OpenSim.Framework.PermissionMask;
41 42
42namespace OpenSim.Region.CoreModules.World.Permissions 43namespace OpenSim.Region.CoreModules.World.Permissions
43{ 44{
@@ -156,9 +157,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
156 157
157 public void Initialise(IConfigSource config) 158 public void Initialise(IConfigSource config)
158 { 159 {
159 IConfig myConfig = config.Configs["Startup"]; 160 string permissionModules = Util.GetConfigVarFromSections<string>(config, "permissionmodules",
160 161 new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule");
161 string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule");
162 162
163 List<string> modules = new List<string>(permissionModules.Split(',')); 163 List<string> modules = new List<string>(permissionModules.Split(','));
164 164
@@ -167,26 +167,34 @@ namespace OpenSim.Region.CoreModules.World.Permissions
167 167
168 m_Enabled = true; 168 m_Enabled = true;
169 169
170 m_allowGridGods = myConfig.GetBoolean("allow_grid_gods", false); 170 m_allowGridGods = Util.GetConfigVarFromSections<bool>(config, "allow_grid_gods",
171 m_bypassPermissions = !myConfig.GetBoolean("serverside_object_permissions", true); 171 new string[] { "Startup", "Permissions" }, false);
172 m_propagatePermissions = myConfig.GetBoolean("propagate_permissions", true); 172 m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(config, "serverside_object_permissions",
173 m_RegionOwnerIsGod = myConfig.GetBoolean("region_owner_is_god", true); 173 new string[] { "Startup", "Permissions" }, true);
174 m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false); 174 m_propagatePermissions = Util.GetConfigVarFromSections<bool>(config, "propagate_permissions",
175 m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true); 175 new string[] { "Startup", "Permissions" }, true);
176 176 m_RegionOwnerIsGod = Util.GetConfigVarFromSections<bool>(config, "region_owner_is_god",
177 m_SimpleBuildPermissions = myConfig.GetBoolean("simple_build_permissions", false); 177 new string[] { "Startup", "Permissions" }, true);
178 m_RegionManagerIsGod = Util.GetConfigVarFromSections<bool>(config, "region_manager_is_god",
179 new string[] { "Startup", "Permissions" }, false);
180 m_ParcelOwnerIsGod = Util.GetConfigVarFromSections<bool>(config, "parcel_owner_is_god",
181 new string[] { "Startup", "Permissions" }, true);
182
183 m_SimpleBuildPermissions = Util.GetConfigVarFromSections<bool>(config, "simple_build_permissions",
184 new string[] { "Startup", "Permissions" }, false);
178 185
179 m_allowedScriptCreators 186 m_allowedScriptCreators
180 = ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators); 187 = ParseUserSetConfigSetting(config, "allowed_script_creators", m_allowedScriptCreators);
181 m_allowedScriptEditors 188 m_allowedScriptEditors
182 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors); 189 = ParseUserSetConfigSetting(config, "allowed_script_editors", m_allowedScriptEditors);
183 190
184 if (m_bypassPermissions) 191 if (m_bypassPermissions)
185 m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks"); 192 m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks");
186 else 193 else
187 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); 194 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
188 195
189 string grant = myConfig.GetString("GrantLSL", ""); 196 string grant = Util.GetConfigVarFromSections<string>(config, "GrantLSL",
197 new string[] { "Startup", "Permissions" }, string.Empty);
190 if (grant.Length > 0) 198 if (grant.Length > 0)
191 { 199 {
192 foreach (string uuidl in grant.Split(',')) 200 foreach (string uuidl in grant.Split(','))
@@ -196,7 +204,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
196 } 204 }
197 } 205 }
198 206
199 grant = myConfig.GetString("GrantCS", ""); 207 grant = Util.GetConfigVarFromSections<string>(config, "GrantCS",
208 new string[] { "Startup", "Permissions" }, string.Empty);
200 if (grant.Length > 0) 209 if (grant.Length > 0)
201 { 210 {
202 foreach (string uuidl in grant.Split(',')) 211 foreach (string uuidl in grant.Split(','))
@@ -206,7 +215,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
206 } 215 }
207 } 216 }
208 217
209 grant = myConfig.GetString("GrantVB", ""); 218 grant = Util.GetConfigVarFromSections<string>(config, "GrantVB",
219 new string[] { "Startup", "Permissions" }, string.Empty);
210 if (grant.Length > 0) 220 if (grant.Length > 0)
211 { 221 {
212 foreach (string uuidl in grant.Split(',')) 222 foreach (string uuidl in grant.Split(','))
@@ -216,7 +226,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
216 } 226 }
217 } 227 }
218 228
219 grant = myConfig.GetString("GrantJS", ""); 229 grant = Util.GetConfigVarFromSections<string>(config, "GrantJS",
230 new string[] { "Startup", "Permissions" }, string.Empty);
220 if (grant.Length > 0) 231 if (grant.Length > 0)
221 { 232 {
222 foreach (string uuidl in grant.Split(',')) 233 foreach (string uuidl in grant.Split(','))
@@ -226,7 +237,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
226 } 237 }
227 } 238 }
228 239
229 grant = myConfig.GetString("GrantYP", ""); 240 grant = Util.GetConfigVarFromSections<string>(config, "GrantYP",
241 new string[] { "Startup", "Permissions" }, string.Empty);
230 if (grant.Length > 0) 242 if (grant.Length > 0)
231 { 243 {
232 foreach (string uuidl in grant.Split(',')) 244 foreach (string uuidl in grant.Split(','))
@@ -464,11 +476,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
464 /// <param name="settingName"></param> 476 /// <param name="settingName"></param>
465 /// <param name="defaultValue">The default value for this attribute</param> 477 /// <param name="defaultValue">The default value for this attribute</param>
466 /// <returns>The parsed value</returns> 478 /// <returns>The parsed value</returns>
467 private static UserSet ParseUserSetConfigSetting(IConfig config, string settingName, UserSet defaultValue) 479 private static UserSet ParseUserSetConfigSetting(IConfigSource config, string settingName, UserSet defaultValue)
468 { 480 {
469 UserSet userSet = defaultValue; 481 UserSet userSet = defaultValue;
470 482
471 string rawSetting = config.GetString(settingName, defaultValue.ToString()); 483 string rawSetting = Util.GetConfigVarFromSections<string>(config, settingName,
484 new string[] {"Startup", "Permissions"}, defaultValue.ToString());
472 485
473 // Temporary measure to allow 'gods' to be specified in config for consistency's sake. In the long term 486 // Temporary measure to allow 'gods' to be specified in config for consistency's sake. In the long term
474 // this should disappear. 487 // 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)