aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs89
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs25
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs414
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs96
-rw-r--r--OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs201
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs285
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs26
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs15
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs169
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs117
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs102
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs103
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs25
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs9
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs13
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs7
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs29
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs9
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs15
-rw-r--r--OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs359
29 files changed, 1667 insertions, 554 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 3ae0dea..b24dc0c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
146 { 146 {
147 DebugLevel = debugLevel; 147 DebugLevel = debugLevel;
148 MainConsole.Instance.OutputFormat( 148 MainConsole.Instance.OutputFormat(
149 "Set event queue debug level to {0} in {1}", DebugLevel, m_scene.Name); 149 "Set attachments debug level to {0} in {1}", DebugLevel, m_scene.Name);
150 } 150 }
151 } 151 }
152 152
@@ -246,8 +246,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
246 string state = sog.GetStateSnapshot(); 246 string state = sog.GetStateSnapshot();
247 ad.AttachmentObjectStates.Add(state); 247 ad.AttachmentObjectStates.Add(state);
248 sp.InTransitScriptStates.Add(state); 248 sp.InTransitScriptStates.Add(state);
249 // Let's remove the scripts of the original object here 249
250 sog.RemoveScriptInstances(true); 250 // Scripts of the originals will be removed when the Agent is successfully removed.
251 // sog.RemoveScriptInstances(true);
251 } 252 }
252 } 253 }
253 } 254 }
@@ -255,6 +256,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
255 256
256 public void CopyAttachments(AgentData ad, IScenePresence sp) 257 public void CopyAttachments(AgentData ad, IScenePresence sp)
257 { 258 {
259// m_log.DebugFormat("[ATTACHMENTS MODULE]: Copying attachment data into {0} in {1}", sp.Name, m_scene.Name);
260
258 if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0) 261 if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0)
259 { 262 {
260 lock (sp.AttachmentsSyncLock) 263 lock (sp.AttachmentsSyncLock)
@@ -265,6 +268,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
265 { 268 {
266 ((SceneObjectGroup)so).LocalId = 0; 269 ((SceneObjectGroup)so).LocalId = 0;
267 ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); 270 ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
271
272// m_log.DebugFormat(
273// "[ATTACHMENTS MODULE]: Copying script state with {0} bytes for object {1} for {2} in {3}",
274// ad.AttachmentObjectStates[i].Length, so.Name, sp.Name, m_scene.Name);
275
268 so.SetState(ad.AttachmentObjectStates[i++], m_scene); 276 so.SetState(ad.AttachmentObjectStates[i++], m_scene);
269 m_scene.IncomingCreateObject(Vector3.Zero, so); 277 m_scene.IncomingCreateObject(Vector3.Zero, so);
270 } 278 }
@@ -331,6 +339,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
331 339
332 340
333 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); 341 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
342
343 // Let's get all items at once, so they get cached
344 UUID[] items = new UUID[attachments.Count];
345 int i = 0;
346 foreach (AvatarAttachment attach in attachments)
347 items[i++] = attach.ItemID;
348 m_scene.InventoryService.GetMultipleItems(sp.UUID, items);
349
334 foreach (AvatarAttachment attach in attachments) 350 foreach (AvatarAttachment attach in attachments)
335 { 351 {
336 uint attachmentPt = (uint)attach.AttachPoint; 352 uint attachmentPt = (uint)attach.AttachPoint;
@@ -378,17 +394,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
378 if (!Enabled) 394 if (!Enabled)
379 return; 395 return;
380 396
381 if (DebugLevel > 0)
382 m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
383
384 List<SceneObjectGroup> attachments = sp.GetAttachments(); 397 List<SceneObjectGroup> attachments = sp.GetAttachments();
385 398
399 if (DebugLevel > 0)
400 m_log.DebugFormat(
401 "[ATTACHMENTS MODULE]: Saving for {0} attachments for {1} in {2}",
402 attachments.Count, sp.Name, m_scene.Name);
403
386 if (attachments.Count <= 0) 404 if (attachments.Count <= 0)
387 return; 405 return;
388 406
389 Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>(); 407 Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>();
390 408
409<<<<<<< HEAD
410 foreach (SceneObjectGroup so in attachments)
411 {
412 // Scripts MUST be snapshotted before the object is
413 // removed from the scene because doing otherwise will
414 // clobber the run flag
415 // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from
416 // scripts performing attachment operations at the same time. Getting object states stops the scripts.
417 scriptStates[so] = PrepareScriptInstanceForSave(so, false);
418
419// m_log.DebugFormat(
420// "[ATTACHMENTS MODULE]: For object {0} for {1} in {2} got saved state {3}",
421// so.Name, sp.Name, m_scene.Name, scriptStates[so]);
422 }
423
424 lock (sp.AttachmentsSyncLock)
425=======
391 if (sp.PresenceType != PresenceType.Npc) 426 if (sp.PresenceType != PresenceType.Npc)
427>>>>>>> avn/ubitvar
392 { 428 {
393 foreach (SceneObjectGroup so in attachments) 429 foreach (SceneObjectGroup so in attachments)
394 { 430 {
@@ -441,7 +477,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
441 if (!Enabled) 477 if (!Enabled)
442 return false; 478 return false;
443 479
480<<<<<<< HEAD
481 group.DetachFromBackup();
482
483 bool success = AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append);
484
485 if (!success)
486 group.AttachToBackup();
487
488 return success;
489=======
444 return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, addToInventory, false, append); 490 return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, addToInventory, false, append);
491>>>>>>> avn/ubitvar
445 } 492 }
446 493
447 /// <summary> 494 /// <summary>
@@ -864,15 +911,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
864 (sbyte)AssetType.Object, 911 (sbyte)AssetType.Object,
865 Utils.StringToBytes(sceneObjectXml), 912 Utils.StringToBytes(sceneObjectXml),
866 sp.UUID); 913 sp.UUID);
867 m_scene.AssetService.Store(asset);
868 914
869 item.AssetID = asset.FullID; 915 if (m_invAccessModule != null)
870 item.Description = asset.Description; 916 m_invAccessModule.UpdateInventoryItemAsset(sp.UUID, item, asset);
871 item.Name = asset.Name;
872 item.AssetType = asset.Type;
873 item.InvType = (int)InventoryType.Object;
874
875 m_scene.InventoryService.UpdateItem(item);
876 917
877 // If the name of the object has been changed whilst attached then we want to update the inventory 918 // If the name of the object has been changed whilst attached then we want to update the inventory
878 // item in the viewer. 919 // item in the viewer.
@@ -907,10 +948,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
907 { 948 {
908 if (DebugLevel > 0) 949 if (DebugLevel > 0)
909 m_log.DebugFormat( 950 m_log.DebugFormat(
910 "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", 951 "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} at pt {2} pos {3} {4} in {5}",
911 so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); 952 so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos, m_scene.Name);
912
913 so.DetachFromBackup();
914 953
915 // Remove from database and parcel prim count 954 // Remove from database and parcel prim count
916 m_scene.DeleteFromStorage(so.UUID); 955 m_scene.DeleteFromStorage(so.UUID);
@@ -986,7 +1025,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
986 InventoryItemBase newItem 1025 InventoryItemBase newItem
987 = m_invAccessModule.CopyToInventory( 1026 = m_invAccessModule.CopyToInventory(
988 DeRezAction.TakeCopy, 1027 DeRezAction.TakeCopy,
989 m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID, 1028 m_scene.InventoryService.GetFolderForType(sp.UUID, FolderType.Object).ID,
990 new List<SceneObjectGroup> { grp }, 1029 new List<SceneObjectGroup> { grp },
991 sp.ControllingClient, true)[0]; 1030 sp.ControllingClient, true)[0];
992 1031
@@ -1015,8 +1054,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1015 private string PrepareScriptInstanceForSave(SceneObjectGroup grp, bool fireDetachEvent) 1054 private string PrepareScriptInstanceForSave(SceneObjectGroup grp, bool fireDetachEvent)
1016 { 1055 {
1017 if (fireDetachEvent) 1056 if (fireDetachEvent)
1057 {
1018 m_scene.EventManager.TriggerOnAttach(grp.LocalId, grp.FromItemID, UUID.Zero); 1058 m_scene.EventManager.TriggerOnAttach(grp.LocalId, grp.FromItemID, UUID.Zero);
1019 1059
1060 // Allow detach event time to do some work before stopping the script
1061 Thread.Sleep(2);
1062 }
1063
1020 using (StringWriter sw = new StringWriter()) 1064 using (StringWriter sw = new StringWriter())
1021 { 1065 {
1022 using (XmlTextWriter writer = new XmlTextWriter(sw)) 1066 using (XmlTextWriter writer = new XmlTextWriter(sw))
@@ -1090,6 +1134,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1090 1134
1091 return null; 1135 return null;
1092 } 1136 }
1137 else if (itemID == UUID.Zero)
1138 {
1139 // We need to have a FromItemID for multiple attachments on a single attach point to appear. This is
1140 // true on Singularity 1.8.5 and quite possibly other viewers as well. As NPCs don't have an inventory
1141 // we will satisfy this requirement by inserting a random UUID.
1142 objatt.FromItemID = UUID.Random();
1143 }
1093 1144
1094 if (DebugLevel > 0) 1145 if (DebugLevel > 0)
1095 m_log.DebugFormat( 1146 m_log.DebugFormat(
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index f023e77..b632774 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -53,7 +53,6 @@ using OpenSim.Region.ScriptEngine.Interfaces;
53using OpenSim.Region.ScriptEngine.XEngine; 53using OpenSim.Region.ScriptEngine.XEngine;
54using OpenSim.Services.Interfaces; 54using OpenSim.Services.Interfaces;
55using OpenSim.Tests.Common; 55using OpenSim.Tests.Common;
56using OpenSim.Tests.Common.Mock;
57 56
58namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests 57namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
59{ 58{
@@ -199,6 +198,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
199 string attName = "att"; 198 string attName = "att";
200 199
201 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); 200 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
201 Assert.That(so.Backup, Is.True);
202 202
203 m_numberOfAttachEventsFired = 0; 203 m_numberOfAttachEventsFired = 0;
204 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false); 204 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false);
@@ -213,6 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
213 Assert.That(attSo.IsAttachment); 213 Assert.That(attSo.IsAttachment);
214 Assert.That(attSo.UsesPhysics, Is.False); 214 Assert.That(attSo.UsesPhysics, Is.False);
215 Assert.That(attSo.IsTemporary, Is.False); 215 Assert.That(attSo.IsTemporary, Is.False);
216 Assert.That(attSo.Backup, Is.False);
216 217
217 // Check item status 218 // Check item status
218 Assert.That( 219 Assert.That(
@@ -223,7 +224,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
223 Assert.That(attachmentItem, Is.Not.Null); 224 Assert.That(attachmentItem, Is.Not.Null);
224 Assert.That(attachmentItem.Name, Is.EqualTo(attName)); 225 Assert.That(attachmentItem.Name, Is.EqualTo(attName));
225 226
226 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); 227 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, FolderType.Object);
227 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); 228 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
228 229
229 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 230 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -270,7 +271,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
270 Assert.That(attachmentItem, Is.Not.Null); 271 Assert.That(attachmentItem, Is.Not.Null);
271 Assert.That(attachmentItem.Name, Is.EqualTo(so.Name)); 272 Assert.That(attachmentItem.Name, Is.EqualTo(so.Name));
272 273
273 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); 274 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, FolderType.Object);
274 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); 275 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
275 276
276 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2)); 277 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2));
@@ -303,7 +304,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
303 Assert.That(attachmentItem, Is.Not.Null); 304 Assert.That(attachmentItem, Is.Not.Null);
304 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); 305 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
305 306
306 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); 307 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, FolderType.Object);
307 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); 308 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
308 309
309 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 310 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -336,7 +337,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
336 Assert.That(attachmentItem, Is.Not.Null); 337 Assert.That(attachmentItem, Is.Not.Null);
337 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); 338 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
338 339
339 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); 340 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, FolderType.Object);
340 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); 341 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
341 342
342 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 343 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -385,7 +386,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
385 public void TestRezAttachmentFromInventory() 386 public void TestRezAttachmentFromInventory()
386 { 387 {
387 TestHelpers.InMethod(); 388 TestHelpers.InMethod();
388// log4net.Config.XmlConfigurator.Configure(); 389// TestHelpers.EnableLogging();
389 390
390 Scene scene = CreateTestScene(); 391 Scene scene = CreateTestScene();
391 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); 392 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
@@ -407,6 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
407 Assert.That(attSo.IsAttachment); 408 Assert.That(attSo.IsAttachment);
408 Assert.That(attSo.UsesPhysics, Is.False); 409 Assert.That(attSo.UsesPhysics, Is.False);
409 Assert.That(attSo.IsTemporary, Is.False); 410 Assert.That(attSo.IsTemporary, Is.False);
411 Assert.IsFalse(attSo.Backup);
410 412
411 // Check appearance status 413 // Check appearance status
412 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); 414 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
@@ -544,7 +546,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
544 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); 546 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
545 TaskInventoryItem scriptItem 547 TaskInventoryItem scriptItem
546 = TaskInventoryHelpers.AddScript( 548 = TaskInventoryHelpers.AddScript(
547 scene, 549 scene.AssetService,
548 so.RootPart, 550 so.RootPart,
549 "scriptItem", 551 "scriptItem",
550 "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }"); 552 "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
@@ -601,7 +603,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
601 Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null); 603 Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null);
602 604
603 // Check object in scene 605 // Check object in scene
604 Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); 606 SceneObjectGroup soInScene = scene.GetSceneObjectGroup("att");
607 Assert.That(soInScene, Is.Not.Null);
608 Assert.IsTrue(soInScene.Backup);
605 609
606 // Check events 610 // Check events
607 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); 611 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
@@ -655,7 +659,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
655 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); 659 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
656 TaskInventoryItem scriptTaskItem 660 TaskInventoryItem scriptTaskItem
657 = TaskInventoryHelpers.AddScript( 661 = TaskInventoryHelpers.AddScript(
658 scene, 662 scene.AssetService,
659 so.RootPart, 663 so.RootPart,
660 "scriptItem", 664 "scriptItem",
661 "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }"); 665 "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
@@ -755,6 +759,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
755 Assert.That(attSo.IsAttachment); 759 Assert.That(attSo.IsAttachment);
756 Assert.That(attSo.UsesPhysics, Is.False); 760 Assert.That(attSo.UsesPhysics, Is.False);
757 Assert.That(attSo.IsTemporary, Is.False); 761 Assert.That(attSo.IsTemporary, Is.False);
762 Assert.IsFalse(attSo.Backup);
758 763
759 // Check appearance status 764 // Check appearance status
760 List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments(); 765 List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
@@ -884,6 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
884 SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0]; 889 SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
885 Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); 890 Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
886 Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); 891 Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
892 Assert.IsFalse(actualSceneBAtt.Backup);
887 893
888 Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1)); 894 Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
889 895
@@ -994,6 +1000,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
994 SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0]; 1000 SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
995 Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); 1001 Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
996 Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); 1002 Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
1003 Assert.IsFalse(actualSceneBAtt.Backup);
997 1004
998 Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1)); 1005 Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
999 1006
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 22f0366..1e9cfba 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
229 private void SendAppearance(ScenePresence sp) 229 private void SendAppearance(ScenePresence sp)
230 { 230 {
231 // Send the appearance to everyone in the scene 231 // Send the appearance to everyone in the scene
232 sp.SendAppearanceToAllOtherAgents(); 232 sp.SendAppearanceToAllOtherClients();
233 233
234 // Send animations back to the avatar as well 234 // Send animations back to the avatar as well
235 sp.Animator.SendAnimPack(); 235 sp.Animator.SendAnimPack();
@@ -529,6 +529,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
529 ); 529 );
530 } 530 }
531 } 531 }
532<<<<<<< HEAD
533
534// m_log.DebugFormat(
535// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
536// face.TextureID, idx, client.Name, client.AgentId);
537=======
532*/ 538*/
533 bool wearableCacheValid = false; 539 bool wearableCacheValid = false;
534 if (wearableCache == null) 540 if (wearableCache == null)
@@ -571,9 +577,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
571 if (wearableCacheValid) 577 if (wearableCacheValid)
572 m_log.Debug("[ValidateBakedCache] have valid local cache"); 578 m_log.Debug("[ValidateBakedCache] have valid local cache");
573 } 579 }
580>>>>>>> avn/ubitvar
574 581
575 bool checkExternal = false; 582 bool checkExternal = false;
576 583
584<<<<<<< HEAD
585 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
586 return false;
587 }
588=======
577 if (!wearableCacheValid) 589 if (!wearableCacheValid)
578 { 590 {
579 // only use external bake module on login condition check 591 // only use external bake module on login condition check
@@ -646,6 +658,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
646 } 658 }
647 } 659 }
648 } 660 }
661>>>>>>> avn/ubitvar
649 662
650 sp.Appearance.WearableCacheItems = wearableCache; 663 sp.Appearance.WearableCacheItems = wearableCache;
651 664
@@ -672,7 +685,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
672 return 0; 685 return 0;
673 686
674 int texturesRebaked = 0; 687 int texturesRebaked = 0;
675 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); 688// IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
676 689
677 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 690 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
678 { 691 {
@@ -688,36 +701,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
688 701
689 if (missingTexturesOnly) 702 if (missingTexturesOnly)
690 { 703 {
691 if (cache != null) 704 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
692 { 705 {
693 if (cache.Check(face.TextureID.ToString())) 706 continue;
694 continue;
695 else
696 {
697 m_log.DebugFormat(
698 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
699 face.TextureID, idx, sp.Name);
700 }
701 } 707 }
702 else 708 else
703 { 709 {
704 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) 710 // On inter-simulator teleports, this occurs if baked textures are not being stored by the
705 { 711 // grid asset service (which means that they are not available to the new region and so have
706 continue; 712 // to be re-requested from the client).
707 } 713 //
708 714 // The only available core OpenSimulator behaviour right now
709 else 715 // is not to store these textures, temporarily or otherwise.
710 { 716 m_log.DebugFormat(
711 // On inter-simulator teleports, this occurs if baked textures are not being stored by the 717 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
712 // grid asset service (which means that they are not available to the new region and so have 718 face.TextureID, idx, sp.Name);
713 // to be re-requested from the client).
714 //
715 // The only available core OpenSimulator behaviour right now
716 // is not to store these textures, temporarily or otherwise.
717 m_log.DebugFormat(
718 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
719 face.TextureID, idx, sp.Name);
720 }
721 } 719 }
722 } 720 }
723 else 721 else
@@ -786,7 +784,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
786 784
787 if (sendTime < now) 785 if (sendTime < now)
788 { 786 {
789 Util.FireAndForget(o => SendAppearance(avatarID)); 787 Util.FireAndForget(o => SendAppearance(avatarID), null, "AvatarFactoryModule.SendAppearance");
790 m_sendqueue.Remove(avatarID); 788 m_sendqueue.Remove(avatarID);
791 } 789 }
792 } 790 }
@@ -804,7 +802,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
804 802
805 if (sendTime < now) 803 if (sendTime < now)
806 { 804 {
807 Util.FireAndForget(o => SaveAppearance(avatarID)); 805 Util.FireAndForget(o => SaveAppearance(avatarID), null, "AvatarFactoryModule.SaveAppearance");
808 m_savequeue.Remove(avatarID); 806 m_savequeue.Remove(avatarID);
809 } 807 }
810 } 808 }
@@ -856,187 +854,238 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
856 m_scene.EventManager.TriggerAvatarAppearanceChanged(sp); 854 m_scene.EventManager.TriggerAvatarAppearanceChanged(sp);
857 } 855 }
858 856
857 /// <summary>
858 /// For a given set of appearance items, check whether the items are valid and add their asset IDs to
859 /// appearance data.
860 /// </summary>
861 /// <param name='userID'></param>
862 /// <param name='appearance'></param>
859 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) 863 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
860 { 864 {
861 IInventoryService invService = m_scene.InventoryService; 865 IInventoryService invService = m_scene.InventoryService;
862 bool resetwearable = false; 866
863 if (invService.GetRootFolder(userID) != null) 867 if (invService.GetRootFolder(userID) != null)
864 { 868 {
865 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 869 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
866 { 870 {
867 for (int j = 0; j < appearance.Wearables[i].Count; j++) 871 for (int j = 0; j < appearance.Wearables[i].Count; j++)
868 { 872 {
869 // Check if the default wearables are not set
870 if (appearance.Wearables[i][j].ItemID == UUID.Zero) 873 if (appearance.Wearables[i][j].ItemID == UUID.Zero)
871 { 874 {
872 switch ((WearableType) i) 875 m_log.WarnFormat(
873 { 876 "[AVFACTORY]: Wearable item {0}:{1} for user {2} unexpectedly UUID.Zero. Ignoring.",
874 case WearableType.Eyes: 877 i, j, userID);
875 case WearableType.Hair:
876 case WearableType.Shape:
877 case WearableType.Skin:
878 //case WearableType.Underpants:
879 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
880 resetwearable = true;
881 m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
882 resetwearable = true;
883 break;
884 878
885 }
886 continue; 879 continue;
887 } 880 }
888 881
889 // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1 882 // Ignore ruth's assets
890 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) 883 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
891 {
892 switch ((WearableType)i)
893 {
894 case WearableType.Eyes:
895 case WearableType.Hair:
896 case WearableType.Shape:
897 case WearableType.Skin:
898 //case WearableType.Underpants:
899 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
900
901 m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
902 resetwearable = true;
903 break;
904
905 }
906 continue; 884 continue;
907 } 885
908
909 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 886 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
910 baseItem = invService.GetItem(baseItem); 887 baseItem = invService.GetItem(baseItem);
911 888
912 if (baseItem != null) 889 if (baseItem != null)
913 { 890 {
914 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); 891 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
915 int unmodifiedWearableIndexForClosure = i;
916 m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
917 delegate(string x, object y, AssetBase z)
918 {
919 if (z == null)
920 {
921 TryAndRepairBrokenWearable(
922 (WearableType)unmodifiedWearableIndexForClosure, invService,
923 userID, appearance);
924 }
925 });
926 } 892 }
927 else 893 else
928 { 894 {
929 m_log.ErrorFormat( 895 m_log.WarnFormat(
930 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", 896 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
931 appearance.Wearables[i][j].ItemID, (WearableType)i); 897 appearance.Wearables[i][j].ItemID, (WearableType)i);
932 898
933 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); 899 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID);
934 resetwearable = true;
935
936 } 900 }
937 } 901 }
938 } 902 }
939
940 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
941 if (appearance.Wearables[(int) WearableType.Eyes] == null)
942 {
943 m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
944
945 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
946 resetwearable = true;
947 }
948 else
949 {
950 if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
951 {
952 m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
953 appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
954 appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
955 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
956 resetwearable = true;
957
958 }
959
960 }
961 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
962 if (appearance.Wearables[(int)WearableType.Shape] == null)
963 {
964 m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
965
966 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
967 resetwearable = true;
968 }
969 else
970 {
971 if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
972 {
973 m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
974 appearance.Wearables[(int)WearableType.Shape][0].ItemID,
975 appearance.Wearables[(int)WearableType.Shape][0].AssetID);
976 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
977 resetwearable = true;
978
979 }
980
981 }
982 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
983 if (appearance.Wearables[(int)WearableType.Hair] == null)
984 {
985 m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
986
987 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
988 resetwearable = true;
989 }
990 else
991 {
992 if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
993 {
994 m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
995 appearance.Wearables[(int)WearableType.Hair][0].ItemID,
996 appearance.Wearables[(int)WearableType.Hair][0].AssetID);
997 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
998 resetwearable = true;
999
1000 }
1001
1002 }
1003 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
1004 if (appearance.Wearables[(int)WearableType.Skin] == null)
1005 {
1006 m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
1007
1008 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
1009 resetwearable = true;
1010 }
1011 else
1012 {
1013 if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
1014 {
1015 m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
1016 appearance.Wearables[(int)WearableType.Skin][0].ItemID,
1017 appearance.Wearables[(int)WearableType.Skin][0].AssetID);
1018 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
1019 resetwearable = true;
1020
1021 }
1022
1023 }
1024 if (resetwearable)
1025 {
1026 ScenePresence presence = null;
1027 if (m_scene.TryGetScenePresence(userID, out presence))
1028 {
1029 presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
1030 presence.Appearance.Serial++);
1031 }
1032 }
1033
1034 } 903 }
1035 else 904 else
1036 { 905 {
1037 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); 906 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
1038 } 907 }
908
909// IInventoryService invService = m_scene.InventoryService;
910// bool resetwearable = false;
911// if (invService.GetRootFolder(userID) != null)
912// {
913// for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
914// {
915// for (int j = 0; j < appearance.Wearables[i].Count; j++)
916// {
917// // Check if the default wearables are not set
918// if (appearance.Wearables[i][j].ItemID == UUID.Zero)
919// {
920// switch ((WearableType) i)
921// {
922// case WearableType.Eyes:
923// case WearableType.Hair:
924// case WearableType.Shape:
925// case WearableType.Skin:
926// //case WearableType.Underpants:
927// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
928// resetwearable = true;
929// m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
930// resetwearable = true;
931// break;
932//
933// }
934// continue;
935// }
936//
937// // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
938// if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
939// {
940// switch ((WearableType)i)
941// {
942// case WearableType.Eyes:
943// case WearableType.Hair:
944// case WearableType.Shape:
945// case WearableType.Skin:
946// //case WearableType.Underpants:
947// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
948//
949// m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
950// resetwearable = true;
951// break;
952//
953// }
954// continue;
955// }
956//
957// InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
958// baseItem = invService.GetItem(baseItem);
959//
960// if (baseItem != null)
961// {
962// appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
963// int unmodifiedWearableIndexForClosure = i;
964// m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
965// delegate(string x, object y, AssetBase z)
966// {
967// if (z == null)
968// {
969// TryAndRepairBrokenWearable(
970// (WearableType)unmodifiedWearableIndexForClosure, invService,
971// userID, appearance);
972// }
973// });
974// }
975// else
976// {
977// m_log.ErrorFormat(
978// "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
979// appearance.Wearables[i][j].ItemID, (WearableType)i);
980//
981// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
982// resetwearable = true;
983//
984// }
985// }
986// }
987//
988// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
989// if (appearance.Wearables[(int) WearableType.Eyes] == null)
990// {
991// m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
992//
993// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
994// resetwearable = true;
995// }
996// else
997// {
998// if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
999// {
1000// m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
1001// appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
1002// appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
1003// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
1004// resetwearable = true;
1005//
1006// }
1007//
1008// }
1009// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
1010// if (appearance.Wearables[(int)WearableType.Shape] == null)
1011// {
1012// m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
1013//
1014// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
1015// resetwearable = true;
1016// }
1017// else
1018// {
1019// if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
1020// {
1021// m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
1022// appearance.Wearables[(int)WearableType.Shape][0].ItemID,
1023// appearance.Wearables[(int)WearableType.Shape][0].AssetID);
1024// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
1025// resetwearable = true;
1026//
1027// }
1028//
1029// }
1030// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
1031// if (appearance.Wearables[(int)WearableType.Hair] == null)
1032// {
1033// m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
1034//
1035// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
1036// resetwearable = true;
1037// }
1038// else
1039// {
1040// if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
1041// {
1042// m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
1043// appearance.Wearables[(int)WearableType.Hair][0].ItemID,
1044// appearance.Wearables[(int)WearableType.Hair][0].AssetID);
1045// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
1046// resetwearable = true;
1047//
1048// }
1049//
1050// }
1051// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
1052// if (appearance.Wearables[(int)WearableType.Skin] == null)
1053// {
1054// m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
1055//
1056// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
1057// resetwearable = true;
1058// }
1059// else
1060// {
1061// if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
1062// {
1063// m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
1064// appearance.Wearables[(int)WearableType.Skin][0].ItemID,
1065// appearance.Wearables[(int)WearableType.Skin][0].AssetID);
1066// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
1067// resetwearable = true;
1068//
1069// }
1070//
1071// }
1072// if (resetwearable)
1073// {
1074// ScenePresence presence = null;
1075// if (m_scene.TryGetScenePresence(userID, out presence))
1076// {
1077// presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
1078// presence.Appearance.Serial++);
1079// }
1080// }
1081//
1082// }
1083// else
1084// {
1085// m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
1086// }
1039 } 1087 }
1088
1040 private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance) 1089 private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
1041 { 1090 {
1042 UUID defaultwearable = GetDefaultItem(type); 1091 UUID defaultwearable = GetDefaultItem(type);
@@ -1050,8 +1099,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
1050 AssetType 1099 AssetType
1051 = 1100 =
1052 (int) 1101 (int)
1053 AssetType 1102 FolderType
1054 .Bodypart, 1103 .BodyPart,
1055 CreatorId 1104 CreatorId
1056 = 1105 =
1057 userID 1106 userID
@@ -1066,8 +1115,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
1066 invService 1115 invService
1067 .GetFolderForType 1116 .GetFolderForType
1068 (userID, 1117 (userID,
1069 AssetType 1118 FolderType
1070 .Bodypart) 1119 .BodyPart)
1071 .ID, 1120 .ID,
1072 Flags = (uint) type, 1121 Flags = (uint) type,
1073 Name = Enum.GetName(typeof (WearableType), type), 1122 Name = Enum.GetName(typeof (WearableType), type),
@@ -1102,8 +1151,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
1102 invService 1151 invService
1103 .GetFolderForType 1152 .GetFolderForType
1104 (userID, 1153 (userID,
1105 AssetType 1154 FolderType
1106 .CurrentOutfitFolder) 1155 .CurrentOutfit)
1107 .ID, 1156 .ID,
1108 Flags = (uint) type, 1157 Flags = (uint) type,
1109 Name = Enum.GetName(typeof (WearableType), type), 1158 Name = Enum.GetName(typeof (WearableType), type),
@@ -1120,12 +1169,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
1120 { 1169 {
1121 m_scene.SendInventoryUpdate(presence.ControllingClient, 1170 m_scene.SendInventoryUpdate(presence.ControllingClient,
1122 invService.GetFolderForType(userID, 1171 invService.GetFolderForType(userID,
1123 AssetType 1172 FolderType
1124 .CurrentOutfitFolder), 1173 .CurrentOutfit),
1125 false, true); 1174 false, true);
1126 } 1175 }
1127 } 1176 }
1128 } 1177 }
1178
1129 private UUID GetDefaultItem(WearableType wearable) 1179 private UUID GetDefaultItem(WearableType wearable)
1130 { 1180 {
1131 // These are ruth 1181 // These are ruth
@@ -1179,7 +1229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
1179 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 1229 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
1180 else 1230 else
1181 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); 1231 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
1182 }); 1232 }, null, "AvatarFactoryModule.OnClientRequestWearables");
1183 } 1233 }
1184 1234
1185 /// <summary> 1235 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
index f090e15..b7ff4e0 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Region.CoreModules.Asset; 34using OpenSim.Region.CoreModules.Asset;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38 37
39namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory 38namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
40{ 39{
@@ -48,23 +47,110 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
48 public void TestSetAppearance() 47 public void TestSetAppearance()
49 { 48 {
50 TestHelpers.InMethod(); 49 TestHelpers.InMethod();
51// log4net.Config.XmlConfigurator.Configure(); 50// TestHelpers.EnableLogging();
51
52 UUID userId = TestHelpers.ParseTail(0x1);
53 UUID bakedTextureID = TestHelpers.ParseTail(0x2);
54
55 // We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly
56 // to the AssetService, which will then store temporary and local assets permanently
57 CoreAssetCache assetCache = new CoreAssetCache();
58
59 AvatarFactoryModule afm = new AvatarFactoryModule();
60 TestScene scene = new SceneHelpers(assetCache).SetupScene();
61 SceneHelpers.SetupSceneModules(scene, afm);
62 ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
63
64 // TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules
65 AssetBase bakedTextureAsset;
66 bakedTextureAsset
67 = new AssetBase(
68 bakedTextureID, "Test Baked Texture", (sbyte)AssetType.Texture, userId.ToString());
69 bakedTextureAsset.Data = new byte[] { 2 }; // Not necessary to have a genuine JPEG2000 asset here yet
70 bakedTextureAsset.Temporary = true;
71 bakedTextureAsset.Local = true;
72 scene.AssetService.Store(bakedTextureAsset);
73
74 byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
75 for (byte i = 0; i < visualParams.Length; i++)
76 visualParams[i] = i;
77
78 Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10));
79 uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes);
80 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
81
82 int rebakeRequestsReceived = 0;
83 ((TestClient)sp.ControllingClient).OnReceivedSendRebakeAvatarTextures += id => rebakeRequestsReceived++;
84
85 // This is the alpha texture
86 eyesFace.TextureID = bakedTextureID;
87 afm.SetAppearance(sp, bakedTextureEntry, visualParams, null);
88
89 Assert.That(rebakeRequestsReceived, Is.EqualTo(0));
90
91 AssetBase eyesBake = scene.AssetService.Get(bakedTextureID.ToString());
92 Assert.That(eyesBake, Is.Not.Null);
93 Assert.That(eyesBake.Temporary, Is.True);
94 Assert.That(eyesBake.Local, Is.True);
95 }
96
97 /// <summary>
98 /// Test appearance setting where the baked texture UUID are library alpha textures.
99 /// </summary>
100 /// <remarks>
101 /// For a mesh avatar, it appears these 'baked textures' are used. So these should not trigger a request to
102 /// rebake.
103 /// </remarks>
104 [Test]
105 public void TestSetAppearanceAlphaBakedTextures()
106 {
107 TestHelpers.InMethod();
108// TestHelpers.EnableLogging();
52 109
53 UUID userId = TestHelpers.ParseTail(0x1); 110 UUID userId = TestHelpers.ParseTail(0x1);
111 UUID alphaTextureID = new UUID("3a367d1c-bef1-6d43-7595-e88c1e3aadb3");
54 112
113 // We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly
114 // to the AssetService, which will then store temporary and local assets permanently
115 CoreAssetCache assetCache = new CoreAssetCache();
116
55 AvatarFactoryModule afm = new AvatarFactoryModule(); 117 AvatarFactoryModule afm = new AvatarFactoryModule();
56 TestScene scene = new SceneHelpers().SetupScene(); 118 TestScene scene = new SceneHelpers(assetCache).SetupScene();
57 SceneHelpers.SetupSceneModules(scene, afm); 119 SceneHelpers.SetupSceneModules(scene, afm);
58 ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); 120 ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
59 121
122 AssetBase libraryAsset;
123 libraryAsset
124 = new AssetBase(
125 alphaTextureID, "Default Alpha Layer Texture", (sbyte)AssetType.Texture, userId.ToString());
126 libraryAsset.Data = new byte[] { 2 }; // Not necessary to have a genuine JPEG2000 asset here yet
127 libraryAsset.Temporary = false;
128 libraryAsset.Local = false;
129 scene.AssetService.Store(libraryAsset);
130
60 byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; 131 byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
61 for (byte i = 0; i < visualParams.Length; i++) 132 for (byte i = 0; i < visualParams.Length; i++)
62 visualParams[i] = i; 133 visualParams[i] = i;
63 134
135<<<<<<< HEAD
136 Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10));
137 uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes);
138 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
139
140 int rebakeRequestsReceived = 0;
141 ((TestClient)sp.ControllingClient).OnReceivedSendRebakeAvatarTextures += id => rebakeRequestsReceived++;
142
143 // This is the alpha texture
144 eyesFace.TextureID = alphaTextureID;
145 afm.SetAppearance(sp, bakedTextureEntry, visualParams, null);
146
147 Assert.That(rebakeRequestsReceived, Is.EqualTo(0));
148=======
64 afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams, new WearableCacheItem[0]); 149 afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams, new WearableCacheItem[0]);
65 150
66 // TODO: Check baked texture 151 // TODO: Check baked texture
67 Assert.AreEqual(visualParams, sp.Appearance.VisualParams); 152 Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
153>>>>>>> avn/ubitvar
68 } 154 }
69 155
70 [Test] 156 [Test]
@@ -102,7 +188,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
102 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); 188 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
103 eyesFace.TextureID = eyesTextureId; 189 eyesFace.TextureID = eyesTextureId;
104 190
191<<<<<<< HEAD
192 afm.SetAppearance(sp, bakedTextureEntry, visualParams, null);
193=======
105 afm.SetAppearance(sp, bakedTextureEntry, visualParams, new WearableCacheItem[0]); 194 afm.SetAppearance(sp, bakedTextureEntry, visualParams, new WearableCacheItem[0]);
195>>>>>>> avn/ubitvar
106 afm.SaveBakedTextures(userId); 196 afm.SaveBakedTextures(userId);
107// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId); 197// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
108 198
diff --git a/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs
new file mode 100644
index 0000000..7d2cad6
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs
@@ -0,0 +1,201 @@
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 OpenMetaverse;
29using Nini.Config;
30using System;
31using System.IO;
32using System.Text;
33using System.Xml;
34using System.Xml.Serialization;
35using System.Collections;
36using System.Collections.Generic;
37using System.Reflection;
38using log4net;
39using OpenSim.Framework;
40using OpenSim.Framework.ServiceAuth;
41using OpenSim.Framework.Communications;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.Interfaces;
45using Mono.Addins;
46
47namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XBakes.Module")]
50 public class XBakesModule : INonSharedRegionModule, IBakedTextureModule
51 {
52 protected Scene m_Scene;
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 private UTF8Encoding enc = new UTF8Encoding();
55 private string m_URL = String.Empty;
56 private static XmlSerializer m_serializer = new XmlSerializer(typeof(AssetBase));
57
58 private static IServiceAuth m_Auth;
59
60 public void Initialise(IConfigSource configSource)
61 {
62 IConfig config = configSource.Configs["XBakes"];
63 if (config == null)
64 return;
65
66 m_URL = config.GetString("URL", String.Empty);
67 m_Auth = ServiceAuth.Create(configSource, "XBakes");
68 }
69
70 public void AddRegion(Scene scene)
71 {
72 // m_log.InfoFormat("[XBakes]: Enabled for region {0}", scene.RegionInfo.RegionName);
73 m_Scene = scene;
74
75 scene.RegisterModuleInterface<IBakedTextureModule>(this);
76 }
77
78 public void RegionLoaded(Scene scene)
79 {
80 }
81
82 public void RemoveRegion(Scene scene)
83 {
84 }
85
86 public void Close()
87 {
88 }
89
90 public string Name
91 {
92 get { return "XBakes.Module"; }
93 }
94
95 public Type ReplaceableInterface
96 {
97 get { return null; }
98 }
99
100 public WearableCacheItem[] Get(UUID id)
101 {
102 if (m_URL == String.Empty)
103 return null;
104
105 int size = 0;
106
107 using (RestClient rc = new RestClient(m_URL))
108 {
109 List<WearableCacheItem> ret = new List<WearableCacheItem>();
110 rc.AddResourcePath("bakes");
111 rc.AddResourcePath(id.ToString());
112
113 rc.RequestMethod = "GET";
114
115 try
116 {
117 Stream s = rc.Request(m_Auth);
118
119 using (XmlTextReader sr = new XmlTextReader(s))
120 {
121 sr.ReadStartElement("BakedAppearance");
122 while (sr.LocalName == "BakedTexture")
123 {
124 string sTextureIndex = sr.GetAttribute("TextureIndex");
125 int lTextureIndex = Convert.ToInt32(sTextureIndex);
126 string sCacheId = sr.GetAttribute("CacheId");
127 UUID lCacheId = UUID.Zero;
128 if (!(UUID.TryParse(sCacheId, out lCacheId)))
129 {
130 // ?? Nothing here
131 }
132
133 ++size;
134
135 sr.ReadStartElement("BakedTexture");
136 AssetBase a = (AssetBase)m_serializer.Deserialize(sr);
137 ret.Add(new WearableCacheItem() { CacheId = lCacheId, TextureIndex = (uint)lTextureIndex, TextureAsset = a, TextureID = a.FullID });
138
139 sr.ReadEndElement();
140 }
141
142 m_log.DebugFormat("[XBakes]: read {0} textures for user {1}", ret.Count, id);
143 }
144
145 return ret.ToArray();
146 }
147 catch (XmlException)
148 {
149 return null;
150 }
151 }
152 }
153
154 public void Store(UUID agentId, WearableCacheItem[] data)
155 {
156 if (m_URL == String.Empty)
157 return;
158
159 MemoryStream reqStream;
160
161 using (MemoryStream bakeStream = new MemoryStream())
162 using (XmlTextWriter bakeWriter = new XmlTextWriter(bakeStream, null))
163 {
164 bakeWriter.WriteStartElement(String.Empty, "BakedAppearance", String.Empty);
165
166 for (int i = 0; i < data.Length; i++)
167 {
168 if (data[i] != null)
169 {
170 bakeWriter.WriteStartElement(String.Empty, "BakedTexture", String.Empty);
171 bakeWriter.WriteAttributeString(String.Empty, "TextureIndex", String.Empty, data[i].TextureIndex.ToString());
172 bakeWriter.WriteAttributeString(String.Empty, "CacheId", String.Empty, data[i].CacheId.ToString());
173 if (data[i].TextureAsset != null)
174 m_serializer.Serialize(bakeWriter, data[i].TextureAsset);
175
176 bakeWriter.WriteEndElement();
177 }
178 }
179
180 bakeWriter.WriteEndElement();
181 bakeWriter.Flush();
182
183 reqStream = new MemoryStream(bakeStream.ToArray());
184 }
185
186 RestClient rc = new RestClient(m_URL);
187 rc.AddResourcePath("bakes");
188 rc.AddResourcePath(agentId.ToString());
189
190 rc.RequestMethod = "POST";
191
192 Util.FireAndForget(
193 delegate
194 {
195 rc.Request(reqStream, m_Auth);
196 m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", data.Length, agentId);
197 }, null, "XBakesModule.Store"
198 );
199 }
200 }
201} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 9d70063..2801ef0 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -214,10 +214,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
214 UUID destination = c.Destination; 214 UUID destination = c.Destination;
215 Vector3 fromPos = c.Position; 215 Vector3 fromPos = c.Position;
216 Vector3 regionPos = new Vector3(scene.RegionInfo.WorldLocX, scene.RegionInfo.WorldLocY, 0); 216 Vector3 regionPos = new Vector3(scene.RegionInfo.WorldLocX, scene.RegionInfo.WorldLocY, 0);
217<<<<<<< HEAD
218=======
217 219
218 bool checkParcelHide = false; 220 bool checkParcelHide = false;
219 UUID sourceParcelID = UUID.Zero; 221 UUID sourceParcelID = UUID.Zero;
220 Vector3 hidePos = fromPos; 222 Vector3 hidePos = fromPos;
223>>>>>>> avn/ubitvar
221 224
222 if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel; 225 if (c.Channel == DEBUG_CHANNEL) c.Type = ChatTypeEnum.DebugChannel;
223 226
@@ -355,22 +358,46 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
355 string fromName = c.From; 358 string fromName = c.From;
356 359
357 UUID fromID = UUID.Zero; 360 UUID fromID = UUID.Zero;
361 UUID ownerID = UUID.Zero;
358 ChatSourceType sourceType = ChatSourceType.Object; 362 ChatSourceType sourceType = ChatSourceType.Object;
359 if (null != c.Sender) 363 if (null != c.Sender)
360 { 364 {
361 ScenePresence avatar = (c.Scene as Scene).GetScenePresence(c.Sender.AgentId); 365 ScenePresence avatar = (c.Scene as Scene).GetScenePresence(c.Sender.AgentId);
362 fromID = c.Sender.AgentId; 366 fromID = c.Sender.AgentId;
363 fromName = avatar.Name; 367 fromName = avatar.Name;
368 ownerID = c.Sender.AgentId;
364 sourceType = ChatSourceType.Agent; 369 sourceType = ChatSourceType.Agent;
365 } 370 }
366 else if (c.SenderUUID != UUID.Zero) 371 else if (c.SenderUUID != UUID.Zero)
367 { 372 {
368 fromID = c.SenderUUID; 373 fromID = c.SenderUUID;
374 ownerID = ((SceneObjectPart)c.SenderObject).OwnerID;
369 } 375 }
370 376
371 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 377 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
372 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 378 HashSet<UUID> receiverIDs = new HashSet<UUID>();
373 379
380<<<<<<< HEAD
381 ((Scene)c.Scene).ForEachRootClient(
382 delegate(IClientAPI client)
383 {
384 // don't forward SayOwner chat from objects to
385 // non-owner agents
386 if ((c.Type == ChatTypeEnum.Owner) &&
387 (null != c.SenderObject) &&
388 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
389 return;
390
391 client.SendChatMessage(
392 c.Message, (byte)cType, CenterOfRegion, fromName, fromID, ownerID,
393 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
394
395 receiverIDs.Add(client.AgentId);
396 });
397
398 (c.Scene as Scene).EventManager.TriggerOnChatToClients(
399 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
400=======
374 if (c.Scene != null) 401 if (c.Scene != null)
375 { 402 {
376 ((Scene)c.Scene).ForEachRootClient 403 ((Scene)c.Scene).ForEachRootClient
@@ -392,6 +419,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
392 (c.Scene as Scene).EventManager.TriggerOnChatToClients( 419 (c.Scene as Scene).EventManager.TriggerOnChatToClients(
393 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); 420 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
394 } 421 }
422>>>>>>> avn/ubitvar
395 } 423 }
396 424
397 /// <summary> 425 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs
new file mode 100644
index 0000000..3018d94
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs
@@ -0,0 +1,285 @@
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 log4net.Config;
31using Nini.Config;
32using NUnit.Framework;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Framework.Servers;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.CoreModules.Avatar.Chat;
38using OpenSim.Region.CoreModules.Framework;
39using OpenSim.Region.CoreModules.Framework.EntityTransfer;
40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Services.Interfaces;
43using OpenSim.Tests.Common;
44
45namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
46{
47 [TestFixture]
48 public class ChatModuleTests : OpenSimTestCase
49 {
50 [TestFixtureSetUp]
51 public void FixtureInit()
52 {
53 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
54 // We must do this here so that child agent positions are updated in a predictable manner.
55 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
56 }
57
58 [TestFixtureTearDown]
59 public void TearDown()
60 {
61 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
62 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
63 // tests really shouldn't).
64 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
65 }
66
67 private void SetupNeighbourRegions(TestScene sceneA, TestScene sceneB)
68 {
69 // XXX: HTTP server is not (and should not be) necessary for this test, though it's absence makes the
70 // CapabilitiesModule complain when it can't set up HTTP endpoints.
71 // BaseHttpServer httpServer = new BaseHttpServer(99999);
72 // MainServer.AddHttpServer(httpServer);
73 // MainServer.Instance = httpServer;
74
75 // We need entity transfer modules so that when sp2 logs into the east region, the region calls
76 // EntityTransferModuleto set up a child agent on the west region.
77 // XXX: However, this is not an entity transfer so is misleading.
78 EntityTransferModule etmA = new EntityTransferModule();
79 EntityTransferModule etmB = new EntityTransferModule();
80 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
81
82 IConfigSource config = new IniConfigSource();
83 config.AddConfig("Chat");
84 IConfig modulesConfig = config.AddConfig("Modules");
85 modulesConfig.Set("EntityTransferModule", etmA.Name);
86 modulesConfig.Set("SimulationServices", lscm.Name);
87
88 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
89 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA, new ChatModule());
90 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB, new ChatModule());
91 }
92
93 /// <summary>
94 /// Tests chat between neighbour regions on the east-west axis
95 /// </summary>
96 /// <remarks>
97 /// Really, this is a combination of a child agent position update test and a chat range test. These need
98 /// to be separated later on.
99 /// </remarks>
100 [Test]
101 public void TestInterRegionChatDistanceEastWest()
102 {
103 TestHelpers.InMethod();
104// TestHelpers.EnableLogging();
105
106 UUID sp1Uuid = TestHelpers.ParseTail(0x11);
107 UUID sp2Uuid = TestHelpers.ParseTail(0x12);
108
109 Vector3 sp1Position = new Vector3(6, 128, 20);
110 Vector3 sp2Position = new Vector3(250, 128, 20);
111
112 SceneHelpers sh = new SceneHelpers();
113 TestScene sceneWest = sh.SetupScene("sceneWest", TestHelpers.ParseTail(0x1), 1000, 1000);
114 TestScene sceneEast = sh.SetupScene("sceneEast", TestHelpers.ParseTail(0x2), 1001, 1000);
115
116 SetupNeighbourRegions(sceneWest, sceneEast);
117
118 ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneEast, sp1Uuid);
119 TestClient sp1Client = (TestClient)sp1.ControllingClient;
120
121 // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0.
122 // TODO: May need to create special complete no-op test physics module rather than basic physics, since
123 // physics is irrelevant to this test.
124 sp1.Flying = true;
125
126 // When sp1 logs in to sceneEast, it sets up a child agent in sceneWest and informs the sp2 client to
127 // make the connection. For this test, will simplify this chain by making the connection directly.
128 ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneWest, sp1Uuid);
129 TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient;
130
131 sp1.AbsolutePosition = sp1Position;
132
133 ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneWest, sp2Uuid);
134 TestClient sp2Client = (TestClient)sp2.ControllingClient;
135 sp2.Flying = true;
136
137 ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneEast, sp2Uuid);
138 TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient;
139
140 sp2.AbsolutePosition = sp2Position;
141
142 // We must update the scenes in order to make the root new root agents trigger position updates in their
143 // children.
144 sceneWest.Update(1);
145 sceneEast.Update(1);
146
147 // Check child positions are correct.
148 Assert.AreEqual(
149 new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z),
150 sp1ChildClient.SceneAgent.AbsolutePosition);
151
152 Assert.AreEqual(
153 new Vector3(sp2Position.X - sceneWest.RegionInfo.RegionSizeX, sp2Position.Y, sp2Position.Z),
154 sp2ChildClient.SceneAgent.AbsolutePosition);
155
156 string receivedSp1ChatMessage = "";
157 string receivedSp2ChatMessage = "";
158
159 sp1ChildClient.OnReceivedChatMessage
160 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message;
161 sp2ChildClient.OnReceivedChatMessage
162 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message;
163
164 TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage);
165 TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage);
166
167 sp1Position = new Vector3(30, 128, 20);
168 sp1.AbsolutePosition = sp1Position;
169 sceneEast.Update(1);
170
171 // Check child position is correct.
172 Assert.AreEqual(
173 new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z),
174 sp1ChildClient.SceneAgent.AbsolutePosition);
175
176 TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage);
177 TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage);
178 }
179
180 /// <summary>
181 /// Tests chat between neighbour regions on the north-south axis
182 /// </summary>
183 /// <remarks>
184 /// Really, this is a combination of a child agent position update test and a chat range test. These need
185 /// to be separated later on.
186 /// </remarks>
187 [Test]
188 public void TestInterRegionChatDistanceNorthSouth()
189 {
190 TestHelpers.InMethod();
191 // TestHelpers.EnableLogging();
192
193 UUID sp1Uuid = TestHelpers.ParseTail(0x11);
194 UUID sp2Uuid = TestHelpers.ParseTail(0x12);
195
196 Vector3 sp1Position = new Vector3(128, 250, 20);
197 Vector3 sp2Position = new Vector3(128, 6, 20);
198
199 SceneHelpers sh = new SceneHelpers();
200 TestScene sceneNorth = sh.SetupScene("sceneNorth", TestHelpers.ParseTail(0x1), 1000, 1000);
201 TestScene sceneSouth = sh.SetupScene("sceneSouth", TestHelpers.ParseTail(0x2), 1000, 1001);
202
203 SetupNeighbourRegions(sceneNorth, sceneSouth);
204
205 ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneNorth, sp1Uuid);
206 TestClient sp1Client = (TestClient)sp1.ControllingClient;
207
208 // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0.
209 // TODO: May need to create special complete no-op test physics module rather than basic physics, since
210 // physics is irrelevant to this test.
211 sp1.Flying = true;
212
213 // When sp1 logs in to sceneEast, it sets up a child agent in sceneNorth and informs the sp2 client to
214 // make the connection. For this test, will simplify this chain by making the connection directly.
215 ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneSouth, sp1Uuid);
216 TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient;
217
218 sp1.AbsolutePosition = sp1Position;
219
220 ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneSouth, sp2Uuid);
221 TestClient sp2Client = (TestClient)sp2.ControllingClient;
222 sp2.Flying = true;
223
224 ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneNorth, sp2Uuid);
225 TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient;
226
227 sp2.AbsolutePosition = sp2Position;
228
229 // We must update the scenes in order to make the root new root agents trigger position updates in their
230 // children.
231 sceneNorth.Update(1);
232 sceneSouth.Update(1);
233
234 // Check child positions are correct.
235 Assert.AreEqual(
236 new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z),
237 sp1ChildClient.SceneAgent.AbsolutePosition);
238
239 Assert.AreEqual(
240 new Vector3(sp2Position.X, sp2Position.Y + sceneSouth.RegionInfo.RegionSizeY, sp2Position.Z),
241 sp2ChildClient.SceneAgent.AbsolutePosition);
242
243 string receivedSp1ChatMessage = "";
244 string receivedSp2ChatMessage = "";
245
246 sp1ChildClient.OnReceivedChatMessage
247 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message;
248 sp2ChildClient.OnReceivedChatMessage
249 += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message;
250
251 TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage);
252 TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage);
253
254 sp1Position = new Vector3(30, 128, 20);
255 sp1.AbsolutePosition = sp1Position;
256 sceneNorth.Update(1);
257
258 // Check child position is correct.
259 Assert.AreEqual(
260 new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z),
261 sp1ChildClient.SceneAgent.AbsolutePosition);
262
263 TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage);
264 TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage);
265 }
266
267 private void TestUserInRange(TestClient speakClient, string testMessage, ref string receivedMessage)
268 {
269 receivedMessage = "";
270
271 speakClient.Chat(0, ChatTypeEnum.Say, testMessage);
272
273 Assert.AreEqual(testMessage, receivedMessage);
274 }
275
276 private void TestUserOutOfRange(TestClient speakClient, string testMessage, ref string receivedMessage)
277 {
278 receivedMessage = "";
279
280 speakClient.Chat(0, ChatTypeEnum.Say, testMessage);
281
282 Assert.AreNotEqual(testMessage, receivedMessage);
283 }
284 }
285} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
index c52d586..b0b7054 100644
--- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
@@ -31,6 +31,7 @@ using Nini.Config;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using OpenSim.Services.Interfaces;
34using OpenMetaverse; 35using OpenMetaverse;
35 36
36using Mono.Addins; 37using Mono.Addins;
@@ -182,8 +183,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
182 try 183 try
183 { 184 {
184 ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 185 ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
186<<<<<<< HEAD
187
188 if (obj == null)
189 return;
190
191=======
185 if (obj == null) 192 if (obj == null)
186 return; 193 return;
194>>>>>>> avn/ubitvar
187 if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0 195 if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0
188 || avatar.Scene.RegionInfo.RegionSettings.AllowDamage) 196 || avatar.Scene.RegionInfo.RegionSettings.AllowDamage)
189 { 197 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index 4fdcd01..56819fa 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -133,13 +133,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
133 UUID objectID, UUID ownerID, string message, UUID textureID, 133 UUID objectID, UUID ownerID, string message, UUID textureID,
134 int ch, string[] buttonlabels) 134 int ch, string[] buttonlabels)
135 { 135 {
136 UserAccount account = m_scene.UserAccountService.GetUserAccount( 136 string username = m_scene.UserManagementModule.GetUserName(ownerID);
137 m_scene.RegionInfo.ScopeID, ownerID); 137 string ownerFirstName, ownerLastName = String.Empty;
138 string ownerFirstName, ownerLastName; 138 if (!String.IsNullOrEmpty(username))
139 if (account != null)
140 { 139 {
141 ownerFirstName = account.FirstName; 140 string[] parts = username.Split(' ');
142 ownerLastName = account.LastName; 141 ownerFirstName = parts[0];
142 if (parts.Length > 1)
143 ownerLastName = username.Split(' ')[1];
143 } 144 }
144 else 145 else
145 { 146 {
@@ -170,17 +171,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
170 } 171 }
171 172
172 public void SendTextBoxToUser(UUID avatarid, string message, 173 public void SendTextBoxToUser(UUID avatarid, string message,
173 int chatChannel, string name, UUID objectid, UUID ownerid) 174 int chatChannel, string name, UUID objectid, UUID ownerID)
174 { 175 {
175 UserAccount account = m_scene.UserAccountService.GetUserAccount( 176 string username = m_scene.UserManagementModule.GetUserName(ownerID);
176 m_scene.RegionInfo.ScopeID, ownerid); 177 string ownerFirstName, ownerLastName = String.Empty;
177 string ownerFirstName, ownerLastName; 178 if (!String.IsNullOrEmpty(username))
178 UUID ownerID = UUID.Zero;
179 if (account != null)
180 { 179 {
181 ownerFirstName = account.FirstName; 180 string[] parts = username.Split(' ');
182 ownerLastName = account.LastName; 181 ownerFirstName = parts[0];
183 ownerID = account.PrincipalID; 182 if (parts.Length > 1)
183 ownerLastName = username.Split(' ')[1];
184 } 184 }
185 else 185 else
186 { 186 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
index b44a5c9..eb23e83 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
@@ -181,7 +181,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
181 if (folderID == UUID.Zero) 181 if (folderID == UUID.Zero)
182 { 182 {
183 InventoryFolderBase folder = inv.GetFolderForType(userID, 183 InventoryFolderBase folder = inv.GetFolderForType(userID,
184 AssetType.CallingCard); 184 FolderType.CallingCard);
185 185
186 if (folder == null) // Nowhere to put it 186 if (folder == null) // Nowhere to put it
187 return UUID.Zero; 187 return UUID.Zero;
@@ -237,7 +237,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
237 IInventoryService invService = m_Scenes[0].InventoryService; 237 IInventoryService invService = m_Scenes[0].InventoryService;
238 238
239 InventoryFolderBase trashFolder = 239 InventoryFolderBase trashFolder =
240 invService.GetFolderForType(client.AgentId, AssetType.TrashFolder); 240 invService.GetFolderForType(client.AgentId, FolderType.Trash);
241 241
242 InventoryItemBase item = new InventoryItemBase(transactionID, client.AgentId); 242 InventoryItemBase item = new InventoryItemBase(transactionID, client.AgentId);
243 item = invService.GetItem(item); 243 item = invService.GetItem(item);
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index b693f2d..7ab568e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -94,6 +94,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
94 protected Dictionary<UUID, UserFriendData> m_Friends = new Dictionary<UUID, UserFriendData>(); 94 protected Dictionary<UUID, UserFriendData> m_Friends = new Dictionary<UUID, UserFriendData>();
95 95
96 /// <summary> 96 /// <summary>
97 /// Maintain a record of clients that need to notify about their online status. This only
98 /// needs to be done on login. Subsequent online/offline friend changes are sent by a different mechanism.
99 /// </summary>
100 protected HashSet<UUID> m_NeedsToNotifyStatus = new HashSet<UUID>();
101
102 /// <summary>
97 /// Maintain a record of viewers that need to be sent notifications for friends that are online. This only 103 /// Maintain a record of viewers that need to be sent notifications for friends that are online. This only
98 /// needs to be done on login. Subsequent online/offline friend changes are sent by a different mechanism. 104 /// needs to be done on login. Subsequent online/offline friend changes are sent by a different mechanism.
99 /// </summary> 105 /// </summary>
@@ -324,6 +330,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
324 private void OnMakeRootAgent(ScenePresence sp) 330 private void OnMakeRootAgent(ScenePresence sp)
325 { 331 {
326 RecacheFriends(sp.ControllingClient); 332 RecacheFriends(sp.ControllingClient);
333
334 lock (m_NeedsToNotifyStatus)
335 {
336 if (m_NeedsToNotifyStatus.Remove(sp.UUID))
337 {
338 // Inform the friends that this user is online. This can only be done once the client is a Root Agent.
339 StatusChange(sp.UUID, true);
340 }
341 }
327 } 342 }
328 343
329 private void OnClientLogin(IClientAPI client) 344 private void OnClientLogin(IClientAPI client)
@@ -331,8 +346,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
331 UUID agentID = client.AgentId; 346 UUID agentID = client.AgentId;
332 347
333 //m_log.DebugFormat("[XXX]: OnClientLogin!"); 348 //m_log.DebugFormat("[XXX]: OnClientLogin!");
334 // Inform the friends that this user is online 349
335 StatusChange(agentID, true); 350 // Register that we need to send this user's status to friends. This can only be done
351 // once the client becomes a Root Agent, because as part of sending out the presence
352 // we also get back the presence of the HG friends, and we need to send that to the
353 // client, but that can only be done when the client is a Root Agent.
354 lock (m_NeedsToNotifyStatus)
355 m_NeedsToNotifyStatus.Add(agentID);
336 356
337 // Register that we need to send the list of online friends to this user 357 // Register that we need to send the list of online friends to this user
338 lock (m_NeedsListOfOnlineFriends) 358 lock (m_NeedsListOfOnlineFriends)
@@ -491,7 +511,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
491 511
492 // Notify about this user status 512 // Notify about this user status
493 StatusNotify(friendList, agentID, online); 513 StatusNotify(friendList, agentID, online);
494 } 514 }, null, "FriendsModule.StatusChange"
495 ); 515 );
496 } 516 }
497 } 517 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs
index ff87ece..13512a2 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -289,18 +289,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
289 289
290 rootElement.AppendChild(result); 290 rootElement.AppendChild(result);
291 291
292 return DocToBytes(doc); 292 return Util.DocToBytes(doc);
293 }
294
295 private byte[] DocToBytes(XmlDocument doc)
296 {
297 MemoryStream ms = new MemoryStream();
298 XmlTextWriter xw = new XmlTextWriter(ms, null);
299 xw.Formatting = Formatting.Indented;
300 doc.WriteTo(xw);
301 xw.Flush();
302
303 return ms.ToArray();
304 } 293 }
305 294
306 #endregion 295 #endregion
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index d00945e..27b7376 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -239,6 +239,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
239 fList.Add(s.Substring(0, 36)); 239 fList.Add(s.Substring(0, 36));
240 } 240 }
241 241
242 // FIXME: also query the presence status of friends in other grids (like in HGStatusNotifier.Notify())
243
242 PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray()); 244 PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
243 foreach (PresenceInfo pi in presence) 245 foreach (PresenceInfo pi in presence)
244 { 246 {
@@ -658,7 +660,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
658 FriendsService.Delete(friendUUI, agentID.ToString()); 660 FriendsService.Delete(friendUUI, agentID.ToString());
659 661
660 // notify the exfriend's service 662 // notify the exfriend's service
661 Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); }); 663 Util.FireAndForget(
664 delegate { Delete(exfriendID, agentID, friendUUI); }, null, "HGFriendsModule.DeleteFriendshipForeignFriend");
662 665
663 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI); 666 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
664 return true; 667 return true;
@@ -676,7 +679,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
676 FriendsService.Delete(agentUUI, exfriendID.ToString()); 679 FriendsService.Delete(agentUUI, exfriendID.ToString());
677 680
678 // notify the agent's service? 681 // notify the agent's service?
679 Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); }); 682 Util.FireAndForget(
683 delegate { Delete(agentID, exfriendID, agentUUI); }, null, "HGFriendsModule.DeleteFriendshipLocalFriend");
680 684
681 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID); 685 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
682 return true; 686 return true;
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
index 961117e..e6fd54e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
@@ -35,7 +35,6 @@ using OpenSim.Framework;
35using OpenSim.Region.CoreModules.Avatar.Friends; 35using OpenSim.Region.CoreModules.Avatar.Friends;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Tests.Common; 37using OpenSim.Tests.Common;
38using OpenSim.Tests.Common.Mock;
39 38
40namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests 39namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
41{ 40{
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
index 7bf19c2..a1b918a 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
@@ -210,10 +210,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
210 success = m_IMService.OutgoingInstantMessage(im, url, foreigner); 210 success = m_IMService.OutgoingInstantMessage(im, url, foreigner);
211 211
212 if (!success && !foreigner) 212 if (!success && !foreigner)
213 HandleUndeliveredMessage(im, result); 213 HandleUndeliverableMessage(im, result);
214 else 214 else
215 result(success); 215 result(success);
216 }); 216 }, null, "HGMessageTransferModule.SendInstantMessage");
217 217
218 return; 218 return;
219 } 219 }
@@ -246,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
246 return successful; 246 return successful;
247 } 247 }
248 248
249 protected void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result) 249 public void HandleUndeliverableMessage(GridInstantMessage im, MessageResultNotification result)
250 { 250 {
251 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage; 251 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
252 252
@@ -282,7 +282,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
282 string uasURL = circuit.ServiceURLs["HomeURI"].ToString(); 282 string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
283 m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL); 283 m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
284 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL); 284 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
285 return uasConn.GetUUI(fromAgent, toAgent); 285
286 string agentUUI = string.Empty;
287 try
288 {
289 agentUUI = uasConn.GetUUI(fromAgent, toAgent);
290 }
291 catch (Exception e) {
292 m_log.Debug("[HG MESSAGE TRANSFER]: GetUUI call failed ", e);
293 }
294
295 return agentUUI;
286 } 296 }
287 } 297 }
288 } 298 }
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index b321adb..5573c94 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
188 SendGridInstantMessageViaXMLRPC(im, result); 188 SendGridInstantMessageViaXMLRPC(im, result);
189 } 189 }
190 190
191 private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result) 191 public void HandleUndeliverableMessage(GridInstantMessage im, MessageResultNotification result)
192 { 192 {
193 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage; 193 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
194 194
@@ -445,7 +445,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
445 return resp; 445 return resp;
446 } 446 }
447 447
448<<<<<<< HEAD
449 /// <summary>
450 /// delegate for sending a grid instant message asynchronously
451 /// </summary>
452 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
453=======
448 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result); 454 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
455>>>>>>> avn/ubitvar
449 456
450 private class GIM { 457 private class GIM {
451 public GridInstantMessage im; 458 public GridInstantMessage im;
@@ -472,25 +479,31 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
472 } 479 }
473 } 480 }
474 481
482<<<<<<< HEAD
483 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
484=======
475 private void GridInstantMessageCompleted(IAsyncResult iar) 485 private void GridInstantMessageCompleted(IAsyncResult iar)
476 { 486 {
477 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState; 487 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
478 d.EndInvoke(iar); 488 d.EndInvoke(iar);
489>>>>>>> avn/ubitvar
479 } 490 }
480 491
481 /// <summary> 492 /// <summary>
482 /// Recursive SendGridInstantMessage over XMLRPC method. 493 /// Internal SendGridInstantMessage over XMLRPC method.
483 /// This is called from within a dedicated thread.
484 /// The first time this is called, prevRegionHandle will be 0 Subsequent times this is called from
485 /// itself, prevRegionHandle will be the last region handle that we tried to send.
486 /// If the handles are the same, we look up the user's location using the grid.
487 /// If the handles are still the same, we end. The send failed.
488 /// </summary> 494 /// </summary>
495<<<<<<< HEAD
496 /// <remarks>
497 /// This is called from within a dedicated thread.
498 /// </remarks>
499 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result)
500=======
489 /// <param name="prevRegionHandle"> 501 /// <param name="prevRegionHandle">
490 /// Pass in 0 the first time this method is called. It will be called recursively with the last 502 /// Pass in 0 the first time this method is called. It will be called recursively with the last
491 /// regionhandle tried 503 /// regionhandle tried
492 /// </param> 504 /// </param>
493 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result) 505 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
506>>>>>>> avn/ubitvar
494 { 507 {
495 GIM gim; 508 GIM gim;
496 do { 509 do {
@@ -516,120 +529,83 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
516 { 529 {
517 530
518 UUID toAgentID = new UUID(im.toAgentID); 531 UUID toAgentID = new UUID(im.toAgentID);
519 532 UUID regionID;
520 PresenceInfo upd = null; 533 bool needToLookupAgent;
521
522 bool lookupAgent = false;
523 534
524 lock (m_UserRegionMap) 535 lock (m_UserRegionMap)
536 needToLookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID);
537
538 while (true)
525 { 539 {
526 if (m_UserRegionMap.ContainsKey(toAgentID)) 540 if (needToLookupAgent)
527 { 541 {
528 upd = new PresenceInfo(); 542 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
529 upd.RegionID = m_UserRegionMap[toAgentID];
530 543
531 // We need to compare the current regionhandle with the previous region handle 544 UUID foundRegionID = UUID.Zero;
532 // or the recursive loop will never end because it will never try to lookup the agent again
533 if (prevRegionID == upd.RegionID)
534 {
535 lookupAgent = true;
536 }
537 }
538 else
539 {
540 lookupAgent = true;
541 }
542 }
543
544 545
545 // Are we needing to look-up an agent? 546 if (presences != null)
546 if (lookupAgent)
547 {
548 // Non-cached user agent lookup.
549 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
550 if (presences != null && presences.Length > 0)
551 {
552 foreach (PresenceInfo p in presences)
553 { 547 {
554 if (p.RegionID != UUID.Zero) 548 foreach (PresenceInfo p in presences)
555 { 549 {
556 upd = p; 550 if (p.RegionID != UUID.Zero)
557 break; 551 {
552 foundRegionID = p.RegionID;
553 break;
554 }
558 } 555 }
559 } 556 }
557
558 // If not found or the found region is the same as the last lookup, then message is undeliverable
559 if (foundRegionID == UUID.Zero || foundRegionID == regionID)
560 break;
561 else
562 regionID = foundRegionID;
560 } 563 }
561 564
562 if (upd != null) 565 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID);
566 if (reginfo == null)
563 { 567 {
564 // check if we've tried this before.. 568 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID);
565 // This is one way to end the recursive loop 569 break;
566 //
567 if (upd.RegionID == prevRegionID)
568 {
569 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
570 HandleUndeliveredMessage(im, result);
571 return;
572 }
573 } 570 }
574 else
575 {
576 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
577 HandleUndeliveredMessage(im, result);
578 return;
579 }
580 }
581 571
572<<<<<<< HEAD
573 // Try to send the message to the agent via the retrieved region.
574 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
575 msgdata["region_handle"] = 0;
576 bool imresult = doIMSending(reginfo, msgdata);
577
578 // If the message delivery was successful, then cache the entry.
579 if (imresult)
580=======
582 if (upd != null) 581 if (upd != null)
583 { 582 {
584 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero, 583 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
585 upd.RegionID); 584 upd.RegionID);
586 if (reginfo != null) 585 if (reginfo != null)
586>>>>>>> avn/ubitvar
587 { 587 {
588 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); 588 lock (m_UserRegionMap)
589 // Not actually used anymore, left in for compatibility
590 // Remove at next interface change
591 //
592 msgdata["region_handle"] = 0;
593 bool imresult = doIMSending(reginfo, msgdata);
594 if (imresult)
595 {
596 // IM delivery successful, so store the Agent's location in our local cache.
597 lock (m_UserRegionMap)
598 {
599 if (m_UserRegionMap.ContainsKey(toAgentID))
600 {
601 m_UserRegionMap[toAgentID] = upd.RegionID;
602 }
603 else
604 {
605 m_UserRegionMap.Add(toAgentID, upd.RegionID);
606 }
607 }
608 result(true);
609 }
610 else
611 { 589 {
612 // try again, but lookup user this time. 590 m_UserRegionMap[toAgentID] = regionID;
613 // Warning, this must call the Async version
614 // of this method or we'll be making thousands of threads
615 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
616 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
617
618 // This is recursive!!!!!
619 SendGridInstantMessageViaXMLRPCAsync(im, result,
620 upd.RegionID);
621 } 591 }
592 result(true);
593 return;
622 } 594 }
623 else 595
624 { 596 // If we reach this point in the first iteration of the while, then we may have unsuccessfully tried
625 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID); 597 // to use a locally cached region ID. All subsequent attempts need to lookup agent details from
626 HandleUndeliveredMessage(im, result); 598 // the presence service.
627 } 599 needToLookupAgent = true;
628 }
629 else
630 {
631 HandleUndeliveredMessage(im, result);
632 } 600 }
601
602 // If we reached this point then the message was not deliverable. Remove the bad cache entry and
603 // signal the delivery failure.
604 lock (m_UserRegionMap)
605 m_UserRegionMap.Remove(toAgentID);
606
607 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
608 HandleUndeliverableMessage(im, result);
633 } 609 }
634 610
635 /// <summary> 611 /// <summary>
@@ -640,7 +616,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
640 /// <returns>Bool if the message was successfully delivered at the other side.</returns> 616 /// <returns>Bool if the message was successfully delivered at the other side.</returns>
641 protected virtual bool doIMSending(GridRegion reginfo, Hashtable xmlrpcdata) 617 protected virtual bool doIMSending(GridRegion reginfo, Hashtable xmlrpcdata)
642 { 618 {
643
644 ArrayList SendParams = new ArrayList(); 619 ArrayList SendParams = new ArrayList();
645 SendParams.Add(xmlrpcdata); 620 SendParams.Add(xmlrpcdata);
646 XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams); 621 XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams);
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 41958b3..76023bd 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -238,6 +238,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
238 return; 238 return;
239 } 239 }
240 240
241<<<<<<< HEAD
242 if (!m_ForwardOfflineGroupMessages)
243 {
244 if (im.dialog == (byte)InstantMessageDialog.GroupNotice ||
245 im.dialog == (byte)InstantMessageDialog.GroupInvitation)
246 return;
247 }
248
249 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
250 "POST", m_RestURL+"/SaveMessage/", im, 10000);
251=======
241 Scene scene = FindScene(new UUID(im.fromAgentID)); 252 Scene scene = FindScene(new UUID(im.fromAgentID));
242 if (scene == null) 253 if (scene == null)
243 scene = m_SceneList[0]; 254 scene = m_SceneList[0];
@@ -245,6 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
245 SendReply reply = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, SendReply>( 256 SendReply reply = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, SendReply>(
246 "POST", m_RestURL+"/SaveMessage/?scope=" + 257 "POST", m_RestURL+"/SaveMessage/?scope=" +
247 scene.RegionInfo.ScopeID.ToString(), im); 258 scene.RegionInfo.ScopeID.ToString(), im);
259>>>>>>> avn/ubitvar
248 260
249 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 261 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
250 { 262 {
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs
index 4c678c2..c2440d8 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs
@@ -49,8 +49,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
49 private static readonly ILog m_log = LogManager.GetLogger( 49 private static readonly ILog m_log = LogManager.GetLogger(
50 MethodBase.GetCurrentMethod().DeclaringType); 50 MethodBase.GetCurrentMethod().DeclaringType);
51 51
52#pragma warning disable 0067
52 public event PresenceChange OnPresenceChange; 53 public event PresenceChange OnPresenceChange;
53 public event BulkPresenceData OnBulkPresenceData; 54 public event BulkPresenceData OnBulkPresenceData;
55#pragma warning restore 0067
54 56
55 protected List<Scene> m_Scenes = new List<Scene>(); 57 protected List<Scene> m_Scenes = new List<Scene>();
56 58
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 5a8544e..4a06fd1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -61,6 +61,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
61 61
62 private UserAccount m_userInfo; 62 private UserAccount m_userInfo;
63 private string m_invPath; 63 private string m_invPath;
64
65 /// <value>
66 /// ID of this request
67 /// </value>
68 protected UUID m_id;
64 69
65 /// <summary> 70 /// <summary>
66 /// Do we want to merge this load with existing inventory? 71 /// Do we want to merge this load with existing inventory?
@@ -71,6 +76,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
71 protected IAssetService m_AssetService; 76 protected IAssetService m_AssetService;
72 protected IUserAccountService m_UserAccountService; 77 protected IUserAccountService m_UserAccountService;
73 78
79 private InventoryArchiverModule m_module;
80
74 /// <value> 81 /// <value>
75 /// The stream from which the inventory archive will be loaded. 82 /// The stream from which the inventory archive will be loaded.
76 /// </value> 83 /// </value>
@@ -114,11 +121,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
114 /// Record the creator id that should be associated with an asset. This is used to adjust asset creator ids 121 /// Record the creator id that should be associated with an asset. This is used to adjust asset creator ids
115 /// after OSP resolution (since OSP creators are only stored in the item 122 /// after OSP resolution (since OSP creators are only stored in the item
116 /// </summary> 123 /// </summary>
117 protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>(); 124 protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
118 125
119 public InventoryArchiveReadRequest( 126 public InventoryArchiveReadRequest(
120 IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) 127 IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge)
128 : this(UUID.Zero, null,
129 inv,
130 assets,
131 uacc,
132 userInfo,
133 invPath,
134 loadPath,
135 merge)
136 {
137 }
138
139 public InventoryArchiveReadRequest(
140 UUID id, InventoryArchiverModule module, IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge)
121 : this( 141 : this(
142 id,
143 module,
122 inv, 144 inv,
123 assets, 145 assets,
124 uacc, 146 uacc,
@@ -130,8 +152,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
130 } 152 }
131 153
132 public InventoryArchiveReadRequest( 154 public InventoryArchiveReadRequest(
133 IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge) 155 UUID id, InventoryArchiverModule module, IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
134 { 156 {
157 m_id = id;
135 m_InventoryService = inv; 158 m_InventoryService = inv;
136 m_AssetService = assets; 159 m_AssetService = assets;
137 m_UserAccountService = uacc; 160 m_UserAccountService = uacc;
@@ -139,6 +162,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
139 m_userInfo = userInfo; 162 m_userInfo = userInfo;
140 m_invPath = invPath; 163 m_invPath = invPath;
141 m_loadStream = loadStream; 164 m_loadStream = loadStream;
165 m_module = module;
142 166
143 // FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things 167 // FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things
144 // (I thought they weren't). We will need to bump the version number and perform this check on all 168 // (I thought they weren't). We will need to bump the version number and perform this check on all
@@ -161,6 +185,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
161 { 185 {
162 try 186 try
163 { 187 {
188 Exception reportedException = null;
189
164 string filePath = "ERROR"; 190 string filePath = "ERROR";
165 191
166 List<InventoryFolderBase> folderCandidates 192 List<InventoryFolderBase> folderCandidates
@@ -197,14 +223,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
197 } 223 }
198 224
199 archive.Close(); 225 archive.Close();
200 226
201 m_log.DebugFormat( 227 m_log.DebugFormat(
202 "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", 228 "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
203 m_successfulAssetRestores, m_failedAssetRestores); 229 m_successfulAssetRestores, m_failedAssetRestores);
204 m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", m_successfulItemRestores); 230
231 //Alicia: When this is called by LibraryModule or Tests, m_module will be null as event is not required
232 if(m_module != null)
233 m_module.TriggerInventoryArchiveLoaded(m_id, true, m_userInfo, m_invPath, m_loadStream, reportedException, m_successfulItemRestores);
205 234
206 return m_loadedNodes; 235 return m_loadedNodes;
207 } 236 }
237 catch(Exception Ex)
238 {
239 // Trigger saved event with failed result and exception data
240 if (m_module != null)
241 m_module.TriggerInventoryArchiveLoaded(m_id, false, m_userInfo, m_invPath, m_loadStream, Ex, 0);
242
243 return m_loadedNodes;
244 }
208 finally 245 finally
209 { 246 {
210 m_loadStream.Close(); 247 m_loadStream.Close();
@@ -375,14 +412,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
375 newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); 412 newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName);
376 UUID newFolderId = UUID.Random(); 413 UUID newFolderId = UUID.Random();
377 414
378 // Asset type has to be Unknown here rather than Folder, otherwise the created folder can't be
379 // deleted once the client has relogged.
380 // The root folder appears to be labelled AssetType.Folder (shows up as "Category" in the client)
381 // even though there is a AssetType.RootCategory
382 destFolder 415 destFolder
383 = new InventoryFolderBase( 416 = new InventoryFolderBase(
384 newFolderId, newFolderName, m_userInfo.PrincipalID, 417 newFolderId, newFolderName, m_userInfo.PrincipalID,
385 (short)AssetType.Unknown, destFolder.ID, 1); 418 (short)FolderType.None, destFolder.ID, 1);
386 m_InventoryService.AddFolder(destFolder); 419 m_InventoryService.AddFolder(destFolder);
387 420
388 // Record that we have now created this folder 421 // Record that we have now created this folder
@@ -483,52 +516,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
483 { 516 {
484 if (m_creatorIdForAssetId.ContainsKey(assetId)) 517 if (m_creatorIdForAssetId.ContainsKey(assetId))
485 { 518 {
486 string xmlData = Utils.BytesToString(data); 519 data = SceneObjectSerializer.ModifySerializedObject(assetId, data,
487 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 520 sog => {
521 bool modified = false;
522
523 foreach (SceneObjectPart sop in sog.Parts)
524 {
525 if (string.IsNullOrEmpty(sop.CreatorData))
526 {
527 sop.CreatorID = m_creatorIdForAssetId[assetId];
528 modified = true;
529 }
530 }
531
532 return modified;
533 });
488 534
489 CoalescedSceneObjects coa = null; 535 if (data == null)
490 if (CoalescedSceneObjectsSerializer.TryFromXml(xmlData, out coa)) 536 return false;
491 {
492// m_log.DebugFormat(
493// "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count);
494
495 if (coa.Objects.Count == 0)
496 {
497 m_log.WarnFormat(
498 "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of coalesced object from asset {0} as it has zero loaded components",
499 assetId);
500 return false;
501 }
502
503 sceneObjects.AddRange(coa.Objects);
504 }
505 else
506 {
507 SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
508
509 if (deserializedObject != null)
510 {
511 sceneObjects.Add(deserializedObject);
512 }
513 else
514 {
515 m_log.WarnFormat(
516 "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of object from asset {0} as deserialization failed",
517 assetId);
518
519 return false;
520 }
521 }
522
523 foreach (SceneObjectGroup sog in sceneObjects)
524 foreach (SceneObjectPart sop in sog.Parts)
525 if (string.IsNullOrEmpty(sop.CreatorData))
526 sop.CreatorID = m_creatorIdForAssetId[assetId];
527
528 if (coa != null)
529 data = Utils.StringToBytes(CoalescedSceneObjectsSerializer.ToXml(coa));
530 else
531 data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sceneObjects[0]));
532 } 537 }
533 } 538 }
534 539
@@ -550,7 +555,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
550 return false; 555 return false;
551 } 556 }
552 } 557 }
553 558
554 /// <summary> 559 /// <summary>
555 /// Load control file 560 /// Load control file
556 /// </summary> 561 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 4292719..f002ad7 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -34,6 +34,7 @@ using System.Xml;
34using log4net; 34using log4net;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Monitoring;
37using OpenSim.Framework.Serialization; 38using OpenSim.Framework.Serialization;
38using OpenSim.Framework.Serialization.External; 39using OpenSim.Framework.Serialization.External;
39using OpenSim.Region.CoreModules.World.Archiver; 40using OpenSim.Region.CoreModules.World.Archiver;
@@ -42,6 +43,8 @@ using OpenSim.Services.Interfaces;
42using Ionic.Zlib; 43using Ionic.Zlib;
43using GZipStream = Ionic.Zlib.GZipStream; 44using GZipStream = Ionic.Zlib.GZipStream;
44using CompressionMode = Ionic.Zlib.CompressionMode; 45using CompressionMode = Ionic.Zlib.CompressionMode;
46using CompressionLevel = Ionic.Zlib.CompressionLevel;
47using PermissionMask = OpenSim.Framework.PermissionMask;
45 48
46namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver 49namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
47{ 50{
@@ -54,6 +57,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
54 /// </summary> 57 /// </summary>
55 public bool SaveAssets { get; set; } 58 public bool SaveAssets { get; set; }
56 59
60 /// <summary>
61 /// Determines which items will be included in the archive, according to their permissions.
62 /// Default is null, meaning no permission checks.
63 /// </summary>
64 public string FilterContent { get; set; }
65
66 /// <summary>
67 /// Counter for inventory items saved to archive for passing to compltion event
68 /// </summary>
69 public int CountItems { get; set; }
70
71 /// <summary>
72 /// Counter for inventory items skipped due to permission filter option for passing to compltion event
73 /// </summary>
74 public int CountFiltered { get; set; }
75
57 /// <value> 76 /// <value>
58 /// Used to select all inventory nodes in a folder but not the folder itself 77 /// Used to select all inventory nodes in a folder but not the folder itself
59 /// </value> 78 /// </value>
@@ -73,12 +92,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
73 /// <value> 92 /// <value>
74 /// ID of this request 93 /// ID of this request
75 /// </value> 94 /// </value>
76 protected Guid m_id; 95 protected UUID m_id;
77
78 /// <value>
79 /// Used to collect the uuids of the assets that we need to save into the archive
80 /// </value>
81 protected Dictionary<UUID, sbyte> m_assetUuids = new Dictionary<UUID, sbyte>();
82 96
83 /// <value> 97 /// <value>
84 /// Used to collect the uuids of the users that we need to save into the archive 98 /// Used to collect the uuids of the users that we need to save into the archive
@@ -94,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
94 /// Constructor 108 /// Constructor
95 /// </summary> 109 /// </summary>
96 public InventoryArchiveWriteRequest( 110 public InventoryArchiveWriteRequest(
97 Guid id, InventoryArchiverModule module, Scene scene, 111 UUID id, InventoryArchiverModule module, Scene scene,
98 UserAccount userInfo, string invPath, string savePath) 112 UserAccount userInfo, string invPath, string savePath)
99 : this( 113 : this(
100 id, 114 id,
@@ -110,7 +124,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
110 /// Constructor 124 /// Constructor
111 /// </summary> 125 /// </summary>
112 public InventoryArchiveWriteRequest( 126 public InventoryArchiveWriteRequest(
113 Guid id, InventoryArchiverModule module, Scene scene, 127 UUID id, InventoryArchiverModule module, Scene scene,
114 UserAccount userInfo, string invPath, Stream saveStream) 128 UserAccount userInfo, string invPath, Stream saveStream)
115 { 129 {
116 m_id = id; 130 m_id = id;
@@ -122,6 +136,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
122 m_assetGatherer = new UuidGatherer(m_scene.AssetService); 136 m_assetGatherer = new UuidGatherer(m_scene.AssetService);
123 137
124 SaveAssets = true; 138 SaveAssets = true;
139 FilterContent = null;
125 } 140 }
126 141
127 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut) 142 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut)
@@ -150,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
150 } 165 }
151 166
152 m_module.TriggerInventoryArchiveSaved( 167 m_module.TriggerInventoryArchiveSaved(
153 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); 168 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException, CountItems, CountFiltered);
154 } 169 }
155 170
156 protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) 171 protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
@@ -166,10 +181,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
166 "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}", 181 "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}",
167 inventoryItem.Name, inventoryItem.ID, path); 182 inventoryItem.Name, inventoryItem.ID, path);
168 } 183 }
184
185 CountFiltered++;
186
169 return; 187 return;
170 } 188 }
171 } 189 }
172 190
191 // Check For Permissions Filter Flags
192 if (!CanUserArchiveObject(m_userInfo.PrincipalID, inventoryItem))
193 {
194 m_log.InfoFormat(
195 "[INVENTORY ARCHIVER]: Insufficient permissions, skipping inventory item {0} {1} at {2}",
196 inventoryItem.Name, inventoryItem.ID, path);
197
198 // Count Items Excluded
199 CountFiltered++;
200
201 return;
202 }
203
173 if (options.ContainsKey("verbose")) 204 if (options.ContainsKey("verbose"))
174 m_log.InfoFormat( 205 m_log.InfoFormat(
175 "[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})", 206 "[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})",
@@ -185,9 +216,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
185 216
186 AssetType itemAssetType = (AssetType)inventoryItem.AssetType; 217 AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
187 218
219 // Count inventory items (different to asset count)
220 CountItems++;
221
188 // Don't chase down link asset items as they actually point to their target item IDs rather than an asset 222 // Don't chase down link asset items as they actually point to their target item IDs rather than an asset
189 if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder) 223 if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
190 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (sbyte)inventoryItem.AssetType, m_assetUuids); 224 m_assetGatherer.AddForInspection(inventoryItem.AssetID);
191 } 225 }
192 226
193 /// <summary> 227 /// <summary>
@@ -243,6 +277,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
243 } 277 }
244 278
245 /// <summary> 279 /// <summary>
280 /// Checks whether the user has permission to export an inventory item to an IAR.
281 /// </summary>
282 /// <param name="UserID">The user</param>
283 /// <param name="InvItem">The inventory item</param>
284 /// <returns>Whether the user is allowed to export the object to an IAR</returns>
285 private bool CanUserArchiveObject(UUID UserID, InventoryItemBase InvItem)
286 {
287 if (FilterContent == null)
288 return true;// Default To Allow Export
289
290 bool permitted = true;
291
292 bool canCopy = (InvItem.CurrentPermissions & (uint)PermissionMask.Copy) != 0;
293 bool canTransfer = (InvItem.CurrentPermissions & (uint)PermissionMask.Transfer) != 0;
294 bool canMod = (InvItem.CurrentPermissions & (uint)PermissionMask.Modify) != 0;
295
296 if (FilterContent.Contains("C") && !canCopy)
297 permitted = false;
298
299 if (FilterContent.Contains("T") && !canTransfer)
300 permitted = false;
301
302 if (FilterContent.Contains("M") && !canMod)
303 permitted = false;
304
305 return permitted;
306 }
307
308 /// <summary>
246 /// Execute the inventory write request 309 /// Execute the inventory write request
247 /// </summary> 310 /// </summary>
248 public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService) 311 public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService)
@@ -250,6 +313,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
250 if (options.ContainsKey("noassets") && (bool)options["noassets"]) 313 if (options.ContainsKey("noassets") && (bool)options["noassets"])
251 SaveAssets = false; 314 SaveAssets = false;
252 315
316 // Set Permission filter if flag is set
317 if (options.ContainsKey("checkPermissions"))
318 {
319 Object temp;
320 if (options.TryGetValue("checkPermissions", out temp))
321 FilterContent = temp.ToString().ToUpper();
322 }
323
253 try 324 try
254 { 325 {
255 InventoryFolderBase inventoryFolder = null; 326 InventoryFolderBase inventoryFolder = null;
@@ -309,7 +380,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
309 // We couldn't find the path indicated 380 // We couldn't find the path indicated
310 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); 381 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
311 Exception e = new InventoryArchiverException(errorMessage); 382 Exception e = new InventoryArchiverException(errorMessage);
312 m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); 383 m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e, 0, 0);
313 throw e; 384 throw e;
314 } 385 }
315 386
@@ -347,16 +418,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
347 418
348 if (SaveAssets) 419 if (SaveAssets)
349 { 420 {
350 m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count); 421 m_assetGatherer.GatherAll();
422
423 m_log.DebugFormat(
424 "[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetGatherer.GatheredUuids.Count);
351 425
352 AssetsRequest ar 426 AssetsRequest ar
353 = new AssetsRequest( 427 = new AssetsRequest(
354 new AssetsArchiver(m_archiveWriter), 428 new AssetsArchiver(m_archiveWriter),
355 m_assetUuids, m_scene.AssetService, 429 m_assetGatherer.GatheredUuids, m_scene.AssetService,
356 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, 430 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
357 options, ReceivedAllAssets); 431 options, ReceivedAllAssets);
358 432
359 Util.FireAndForget(o => ar.Execute()); 433 WorkManager.RunInThread(o => ar.Execute(), null, string.Format("AssetsRequest ({0})", m_scene.Name));
360 } 434 }
361 else 435 else
362 { 436 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index ea660bd..5295ba3 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -57,6 +57,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
57// public bool DisablePresenceChecks { get; set; } 57// public bool DisablePresenceChecks { get; set; }
58 58
59 public event InventoryArchiveSaved OnInventoryArchiveSaved; 59 public event InventoryArchiveSaved OnInventoryArchiveSaved;
60 public event InventoryArchiveLoaded OnInventoryArchiveLoaded;
60 61
61 /// <summary> 62 /// <summary>
62 /// The file to load and save inventory if no filename has been specified 63 /// The file to load and save inventory if no filename has been specified
@@ -64,9 +65,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
64 protected const string DEFAULT_INV_BACKUP_FILENAME = "user-inventory.iar"; 65 protected const string DEFAULT_INV_BACKUP_FILENAME = "user-inventory.iar";
65 66
66 /// <value> 67 /// <value>
67 /// Pending save completions initiated from the console 68 /// Pending save and load completions initiated from the console
68 /// </value> 69 /// </value>
69 protected List<Guid> m_pendingConsoleSaves = new List<Guid>(); 70 protected List<UUID> m_pendingConsoleTasks = new List<UUID>();
70 71
71 /// <value> 72 /// <value>
72 /// All scenes that this module knows about 73 /// All scenes that this module knows about
@@ -111,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
111 { 112 {
112 scene.RegisterModuleInterface<IInventoryArchiverModule>(this); 113 scene.RegisterModuleInterface<IInventoryArchiverModule>(this);
113 OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; 114 OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
115 OnInventoryArchiveLoaded += LoadInvConsoleCommandCompleted;
114 116
115 scene.AddCommand( 117 scene.AddCommand(
116 "Archiving", this, "load iar", 118 "Archiving", this, "load iar",
@@ -139,7 +141,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
139 + "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine 141 + "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine
140 + "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine 142 + "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine
141 + "-v|--verbose extra debug messages.\n" 143 + "-v|--verbose extra debug messages.\n"
142 + "--noassets stops assets being saved to the IAR.", 144 + "--noassets stops assets being saved to the IAR."
145 + "--perm=<permissions> stops items with insufficient permissions from being saved to the IAR.\n"
146 + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer, \"M\" = Modify.\n",
143 HandleSaveInvConsoleCommand); 147 HandleSaveInvConsoleCommand);
144 148
145 m_aScene = scene; 149 m_aScene = scene;
@@ -175,22 +179,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
175 /// Trigger the inventory archive saved event. 179 /// Trigger the inventory archive saved event.
176 /// </summary> 180 /// </summary>
177 protected internal void TriggerInventoryArchiveSaved( 181 protected internal void TriggerInventoryArchiveSaved(
178 Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, 182 UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
179 Exception reportedException) 183 Exception reportedException, int SaveCount, int FilterCount)
180 { 184 {
181 InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; 185 InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved;
182 if (handlerInventoryArchiveSaved != null) 186 if (handlerInventoryArchiveSaved != null)
183 handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); 187 handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException, SaveCount , FilterCount);
188 }
189
190 /// <summary>
191 /// Trigger the inventory archive loaded event.
192 /// </summary>
193 protected internal void TriggerInventoryArchiveLoaded(
194 UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream,
195 Exception reportedException, int LoadCount)
196 {
197 InventoryArchiveLoaded handlerInventoryArchiveLoaded = OnInventoryArchiveLoaded;
198 if (handlerInventoryArchiveLoaded != null)
199 handlerInventoryArchiveLoaded(id, succeeded, userInfo, invPath, loadStream, reportedException, LoadCount);
184 } 200 }
185 201
186 public bool ArchiveInventory( 202 public bool ArchiveInventory(
187 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) 203 UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
188 { 204 {
189 return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>()); 205 return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>());
190 } 206 }
191 207
192 public bool ArchiveInventory( 208 public bool ArchiveInventory(
193 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, 209 UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
194 Dictionary<string, object> options) 210 Dictionary<string, object> options)
195 { 211 {
196 if (m_scenes.Count > 0) 212 if (m_scenes.Count > 0)
@@ -230,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
230 } 246 }
231 247
232 public bool ArchiveInventory( 248 public bool ArchiveInventory(
233 Guid id, string firstName, string lastName, string invPath, string pass, string savePath, 249 UUID id, string firstName, string lastName, string invPath, string pass, string savePath,
234 Dictionary<string, object> options) 250 Dictionary<string, object> options)
235 { 251 {
236// if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath)) 252// if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath))
@@ -272,13 +288,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
272 return false; 288 return false;
273 } 289 }
274 290
275 public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream) 291 public bool DearchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream)
276 { 292 {
277 return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); 293 return DearchiveInventory(id, firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
278 } 294 }
279 295
280 public bool DearchiveInventory( 296 public bool DearchiveInventory(
281 string firstName, string lastName, string invPath, string pass, Stream loadStream, 297 UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream,
282 Dictionary<string, object> options) 298 Dictionary<string, object> options)
283 { 299 {
284 if (m_scenes.Count > 0) 300 if (m_scenes.Count > 0)
@@ -294,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
294 310
295 try 311 try
296 { 312 {
297 request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge); 313 request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge);
298 } 314 }
299 catch (EntryPointNotFoundException e) 315 catch (EntryPointNotFoundException e)
300 { 316 {
@@ -326,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
326 } 342 }
327 343
328 public bool DearchiveInventory( 344 public bool DearchiveInventory(
329 string firstName, string lastName, string invPath, string pass, string loadPath, 345 UUID id, string firstName, string lastName, string invPath, string pass, string loadPath,
330 Dictionary<string, object> options) 346 Dictionary<string, object> options)
331 { 347 {
332 if (m_scenes.Count > 0) 348 if (m_scenes.Count > 0)
@@ -342,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
342 358
343 try 359 try
344 { 360 {
345 request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge); 361 request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge);
346 } 362 }
347 catch (EntryPointNotFoundException e) 363 catch (EntryPointNotFoundException e)
348 { 364 {
@@ -378,6 +394,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
378 { 394 {
379 try 395 try
380 { 396 {
397 UUID id = UUID.Random();
398
381 Dictionary<string, object> options = new Dictionary<string, object>(); 399 Dictionary<string, object> options = new Dictionary<string, object>();
382 OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); 400 OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
383 401
@@ -400,10 +418,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
400 "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", 418 "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}",
401 loadPath, invPath, firstName, lastName); 419 loadPath, invPath, firstName, lastName);
402 420
403 if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) 421 lock (m_pendingConsoleTasks)
404 m_log.InfoFormat( 422 m_pendingConsoleTasks.Add(id);
405 "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", 423
406 loadPath, firstName, lastName); 424 DearchiveInventory(id, firstName, lastName, invPath, pass, loadPath, options);
407 } 425 }
408 catch (InventoryArchiverException e) 426 catch (InventoryArchiverException e)
409 { 427 {
@@ -417,7 +435,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
417 /// <param name="cmdparams"></param> 435 /// <param name="cmdparams"></param>
418 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams) 436 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
419 { 437 {
420 Guid id = Guid.NewGuid(); 438 UUID id = UUID.Random();
421 439
422 Dictionary<string, object> options = new Dictionary<string, object>(); 440 Dictionary<string, object> options = new Dictionary<string, object>();
423 441
@@ -439,6 +457,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
439 options["excludefolders"] = new List<String>(); 457 options["excludefolders"] = new List<String>();
440 ((List<String>)options["excludefolders"]).Add(v); 458 ((List<String>)options["excludefolders"]).Add(v);
441 }); 459 });
460 ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
442 461
443 List<string> mainParams = ops.Parse(cmdparams); 462 List<string> mainParams = ops.Parse(cmdparams);
444 463
@@ -464,8 +483,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
464 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", 483 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
465 savePath, invPath, firstName, lastName); 484 savePath, invPath, firstName, lastName);
466 485
467 lock (m_pendingConsoleSaves) 486 lock (m_pendingConsoleTasks)
468 m_pendingConsoleSaves.Add(id); 487 m_pendingConsoleTasks.Add(id);
469 488
470 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); 489 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
471 } 490 }
@@ -476,20 +495,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
476 } 495 }
477 496
478 private void SaveInvConsoleCommandCompleted( 497 private void SaveInvConsoleCommandCompleted(
479 Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, 498 UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
480 Exception reportedException) 499 Exception reportedException, int SaveCount, int FilterCount)
481 { 500 {
482 lock (m_pendingConsoleSaves) 501 lock (m_pendingConsoleTasks)
483 { 502 {
484 if (m_pendingConsoleSaves.Contains(id)) 503 if (m_pendingConsoleTasks.Contains(id))
485 m_pendingConsoleSaves.Remove(id); 504 m_pendingConsoleTasks.Remove(id);
486 else 505 else
487 return; 506 return;
488 } 507 }
489 508
490 if (succeeded) 509 if (succeeded)
491 { 510 {
492 m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName); 511 // Report success and include item count and filter count (Skipped items due to --perm or --exclude switches)
512 if(FilterCount == 0)
513 m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}", SaveCount, userInfo.FirstName, userInfo.LastName);
514 else
515 m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}. Skipped {3} items due to exclude and/or perm switches", SaveCount, userInfo.FirstName, userInfo.LastName, FilterCount);
493 } 516 }
494 else 517 else
495 { 518 {
@@ -499,6 +522,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
499 } 522 }
500 } 523 }
501 524
525 private void LoadInvConsoleCommandCompleted(
526 UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream,
527 Exception reportedException, int LoadCount)
528 {
529 lock (m_pendingConsoleTasks)
530 {
531 if (m_pendingConsoleTasks.Contains(id))
532 m_pendingConsoleTasks.Remove(id);
533 else
534 return;
535 }
536
537 if (succeeded)
538 {
539 m_log.InfoFormat("[INVENTORY ARCHIVER]: Loaded {0} items from archive {1} for {2} {3}", LoadCount, invPath, userInfo.FirstName, userInfo.LastName);
540 }
541 else
542 {
543 m_log.ErrorFormat(
544 "[INVENTORY ARCHIVER]: Archive load for {0} {1} failed - {2}",
545 userInfo.FirstName, userInfo.LastName, reportedException.Message);
546 }
547 }
548
502 /// <summary> 549 /// <summary>
503 /// Get user information for the given name. 550 /// Get user information for the given name.
504 /// </summary> 551 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs
index 08f199a..84f9f3f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 48{
@@ -69,8 +68,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
69 68
70 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood"); 69 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood");
71 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); 70 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
72 71
73 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); 72 archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
74 InventoryItemBase foundItem1 73 InventoryItemBase foundItem1
75 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); 74 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
76 75
@@ -79,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
79 // Now try loading to a root child folder 78 // Now try loading to a root child folder
80 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false); 79 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false);
81 MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); 80 MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray());
82 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); 81 archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream);
83 82
84 InventoryItemBase foundItem2 83 InventoryItemBase foundItem2
85 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name); 84 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name);
@@ -88,7 +87,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
88 // Now try loading to a more deeply nested folder 87 // Now try loading to a more deeply nested folder
89 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false); 88 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false);
90 archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); 89 archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
91 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); 90 archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream);
92 91
93 InventoryItemBase foundItem3 92 InventoryItemBase foundItem3
94 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name); 93 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name);
@@ -110,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
110 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 109 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
111 110
112 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); 111 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
113 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); 112 archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
114 113
115 InventoryItemBase foundItem1 114 InventoryItemBase foundItem1
116 = InventoryArchiveUtils.FindItemByPath( 115 = InventoryArchiveUtils.FindItemByPath(
@@ -180,13 +179,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
180 179
181 mre.Reset(); 180 mre.Reset();
182 archiverModule.ArchiveInventory( 181 archiverModule.ArchiveInventory(
183 Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); 182 UUID.Random(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
184 mre.WaitOne(60000, false); 183 mre.WaitOne(60000, false);
185 184
186 // LOAD ITEM 185 // LOAD ITEM
187 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); 186 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
188 187
189 archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream); 188 archiverModule.DearchiveInventory(UUID.Random(), userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
190 189
191 InventoryItemBase foundItem1 190 InventoryItemBase foundItem1
192 = InventoryArchiveUtils.FindItemByPath( 191 = InventoryArchiveUtils.FindItemByPath(
@@ -229,7 +228,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
229 228
230 { 229 {
231 // Test replication of path1 230 // Test replication of path1
232 new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) 231 new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
233 .ReplicateArchivePathToUserInventory( 232 .ReplicateArchivePathToUserInventory(
234 iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), 233 iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
235 foldersCreated, nodesLoaded); 234 foldersCreated, nodesLoaded);
@@ -246,7 +245,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
246 245
247 { 246 {
248 // Test replication of path2 247 // Test replication of path2
249 new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) 248 new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
250 .ReplicateArchivePathToUserInventory( 249 .ReplicateArchivePathToUserInventory(
251 iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), 250 iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
252 foldersCreated, nodesLoaded); 251 foldersCreated, nodesLoaded);
@@ -292,7 +291,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
292 291
293 string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); 292 string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
294 293
295 new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) 294 new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
296 .ReplicateArchivePathToUserInventory( 295 .ReplicateArchivePathToUserInventory(
297 itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), 296 itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
298 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); 297 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
@@ -343,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
343 342
344 string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); 343 string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
345 344
346 new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true) 345 new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true)
347 .ReplicateArchivePathToUserInventory( 346 .ReplicateArchivePathToUserInventory(
348 itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), 347 itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
349 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); 348 new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs
index 1b521fc..d5f3a22 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 48{
@@ -72,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
72// TestHelpers.EnableLogging(); 71// TestHelpers.EnableLogging();
73 72
74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); 73 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
75 m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream); 74 m_archiverModule.DearchiveInventory(UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
76 75
77 InventoryItemBase coaItem 76 InventoryItemBase coaItem
78 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName); 77 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName);
@@ -106,8 +105,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
106// log4net.Config.XmlConfigurator.Configure(); 105// log4net.Config.XmlConfigurator.Configure();
107 106
108 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); 107 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
109 108
110 m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream); 109 m_archiverModule.DearchiveInventory(UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream);
111 InventoryItemBase foundItem1 110 InventoryItemBase foundItem1
112 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name); 111 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name);
113 112
@@ -171,7 +170,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
171// log4net.Config.XmlConfigurator.Configure(); 170// log4net.Config.XmlConfigurator.Configure();
172 171
173 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); 172 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
174 m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream); 173 m_archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream);
175 174
176 InventoryItemBase foundItem1 175 InventoryItemBase foundItem1
177 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); 176 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs
index b85739e..b614c18 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 48{
@@ -85,8 +84,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
85 byte[] data = tar.ReadEntry(out filePath, out tarEntryType); 84 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
86 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 85 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
87 86
88 InventoryArchiveReadRequest iarr 87 InventoryArchiveReadRequest iarr
89 = new InventoryArchiveReadRequest(null, null, null, null, null, (Stream)null, false); 88 = new InventoryArchiveReadRequest(UUID.Random(), null, null, null, null, null, null, (Stream)null, false);
90 iarr.LoadControlFile(filePath, data); 89 iarr.LoadControlFile(filePath, data);
91 90
92 Assert.That(iarr.ControlFileLoaded, Is.True); 91 Assert.That(iarr.ControlFileLoaded, Is.True);
@@ -110,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
110 109
111 mre.Reset(); 110 mre.Reset();
112 m_archiverModule.ArchiveInventory( 111 m_archiverModule.ArchiveInventory(
113 Guid.NewGuid(), userFirstName, userLastName, "/", userPassword, archiveWriteStream); 112 UUID.Random(), userFirstName, userLastName, "/", userPassword, archiveWriteStream);
114 mre.WaitOne(60000, false); 113 mre.WaitOne(60000, false);
115 114
116 // Test created iar 115 // Test created iar
@@ -179,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
179 178
180 mre.Reset(); 179 mre.Reset();
181 m_archiverModule.ArchiveInventory( 180 m_archiverModule.ArchiveInventory(
182 Guid.NewGuid(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream); 181 UUID.Random(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream);
183 mre.WaitOne(60000, false); 182 mre.WaitOne(60000, false);
184 183
185 // Test created iar 184 // Test created iar
@@ -267,7 +266,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
267 266
268 mre.Reset(); 267 mre.Reset();
269 m_archiverModule.ArchiveInventory( 268 m_archiverModule.ArchiveInventory(
270 Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream); 269 UUID.Random(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream);
271 mre.WaitOne(60000, false); 270 mre.WaitOne(60000, false);
272 271
273 byte[] archive = archiveWriteStream.ToArray(); 272 byte[] archive = archiveWriteStream.ToArray();
@@ -364,7 +363,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
364 363
365 // When we're not saving assets, archiving is being done synchronously. 364 // When we're not saving assets, archiving is being done synchronously.
366 m_archiverModule.ArchiveInventory( 365 m_archiverModule.ArchiveInventory(
367 Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options); 366 UUID.Random(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options);
368 367
369 byte[] archive = archiveWriteStream.ToArray(); 368 byte[] archive = archiveWriteStream.ToArray();
370 MemoryStream archiveReadStream = new MemoryStream(archive); 369 MemoryStream archiveReadStream = new MemoryStream(archive);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
index db78da9..4b015d7 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 48{
@@ -163,14 +162,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
163 scene.AddInventoryItem(coaItem); 162 scene.AddInventoryItem(coaItem);
164 163
165 archiverModule.ArchiveInventory( 164 archiverModule.ArchiveInventory(
166 Guid.NewGuid(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream); 165 UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream);
167 166
168 m_iarStreamBytes = archiveWriteStream.ToArray(); 167 m_iarStreamBytes = archiveWriteStream.ToArray();
169 } 168 }
170 169
171 protected void SaveCompleted( 170 protected void SaveCompleted(
172 Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, 171 UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
173 Exception reportedException) 172 Exception reportedException, int SaveCount, int FilterCount)
174 { 173 {
175 mre.Set(); 174 mre.Set();
176 } 175 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 3815c71..18e18a9 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -180,8 +180,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
180 "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory", 180 "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory",
181 folderID, new UUID(im.toAgentID)); 181 folderID, new UUID(im.toAgentID));
182 182
183<<<<<<< HEAD
184 InventoryFolderBase folderCopy
185 = scene.GiveInventoryFolder(client, receipientID, client.AgentId, folderID, UUID.Zero);
186=======
183 InventoryFolderBase folderCopy 187 InventoryFolderBase folderCopy
184 = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero); 188 = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero);
189>>>>>>> avn/ubitvar
185 190
186 if (folderCopy == null) 191 if (folderCopy == null)
187 { 192 {
@@ -217,13 +222,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
217 "into agent {1}'s inventory", 222 "into agent {1}'s inventory",
218 itemID, new UUID(im.toAgentID)); 223 itemID, new UUID(im.toAgentID));
219 224
220 InventoryItemBase itemCopy = scene.GiveInventoryItem( 225 string message;
221 new UUID(im.toAgentID), 226 InventoryItemBase itemCopy = scene.GiveInventoryItem(new UUID(im.toAgentID), client.AgentId, itemID, out message);
222 client.AgentId, itemID);
223 227
224 if (itemCopy == null) 228 if (itemCopy == null)
225 { 229 {
226 client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); 230 client.SendAgentAlertMessage(message, false);
227 return; 231 return;
228 } 232 }
229 233
@@ -389,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
389 IInventoryService invService = scene.InventoryService; 393 IInventoryService invService = scene.InventoryService;
390 394
391 InventoryFolderBase trashFolder = 395 InventoryFolderBase trashFolder =
392 invService.GetFolderForType(client.AgentId, AssetType.TrashFolder); 396 invService.GetFolderForType(client.AgentId, FolderType.Trash);
393 397
394 UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip 398 UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
395 399
@@ -471,6 +475,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
471 /// <param name="im"></param> 475 /// <param name="im"></param>
472 private void OnGridInstantMessage(GridInstantMessage im) 476 private void OnGridInstantMessage(GridInstantMessage im)
473 { 477 {
478<<<<<<< HEAD
479 // Check if it's a type of message that we should handle
480 if (!((im.dialog == (byte) InstantMessageDialog.InventoryOffered)
481 || (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered)
482 || (im.dialog == (byte) InstantMessageDialog.InventoryAccepted)
483 || (im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
484 || (im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined)))
485 return;
486
487 m_log.DebugFormat(
488 "[INVENTORY TRANSFER]: {0} IM type received from grid. From={1} ({2}), To={3}",
489 (InstantMessageDialog)im.dialog, im.fromAgentID, im.fromAgentName, im.toAgentID);
490
491=======
492>>>>>>> avn/ubitvar
474 // Check if this is ours to handle 493 // Check if this is ours to handle
475 // 494 //
476 Scene scene = FindClientScene(new UUID(im.toAgentID)); 495 Scene scene = FindClientScene(new UUID(im.toAgentID));
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs
index 162a0c3..7ddc396 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs
@@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock;
43 42
44namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests 43namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests
45{ 44{
@@ -237,8 +236,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests
237 InventoryItemBase receivedItem 236 InventoryItemBase receivedItem
238 = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, receiverSp.UUID, "Trash/givenObj"); 237 = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, receiverSp.UUID, "Trash/givenObj");
239 238
240 InventoryFolderBase trashFolder 239 InventoryFolderBase trashFolder
241 = m_scene.InventoryService.GetFolderForType(receiverSp.UUID, AssetType.TrashFolder); 240 = m_scene.InventoryService.GetFolderForType(receiverSp.UUID, FolderType.Trash);
242 241
243 Assert.That(receivedItem, Is.Not.Null); 242 Assert.That(receivedItem, Is.Not.Null);
244 Assert.That(receivedItem.ID, Is.Not.EqualTo(originalItem.ID)); 243 Assert.That(receivedItem.ID, Is.Not.EqualTo(originalItem.ID));
@@ -430,8 +429,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests
430 InventoryFolderBase receivedFolder 429 InventoryFolderBase receivedFolder
431 = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, receiverSp.UUID, "Trash/f1"); 430 = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, receiverSp.UUID, "Trash/f1");
432 431
433 InventoryFolderBase trashFolder 432 InventoryFolderBase trashFolder
434 = m_scene.InventoryService.GetFolderForType(receiverSp.UUID, AssetType.TrashFolder); 433 = m_scene.InventoryService.GetFolderForType(receiverSp.UUID, FolderType.Trash);
435 434
436 Assert.That(receivedFolder, Is.Not.Null); 435 Assert.That(receivedFolder, Is.Not.Null);
437 Assert.That(receivedFolder.ID, Is.Not.EqualTo(originalFolder.ID)); 436 Assert.That(receivedFolder.ID, Is.Not.EqualTo(originalFolder.ID));
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index a34f2d2..24286a4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -239,16 +239,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
239 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector(); 239 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
240 GridRegion gatekeeper = new GridRegion(); 240 GridRegion gatekeeper = new GridRegion();
241 gatekeeper.ServerURI = url; 241 gatekeeper.ServerURI = url;
242 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID)); 242 string homeURI = scene.GetAgentHomeURI(client.AgentId);
243
244 string message;
245 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID), client.AgentId, homeURI, out message);
243 if (finalDestination != null) 246 if (finalDestination != null)
244 { 247 {
245 ScenePresence sp = scene.GetScenePresence(client.AgentId); 248 ScenePresence sp = scene.GetScenePresence(client.AgentId);
246 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); 249 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
247 250
248 if (transferMod != null && sp != null) 251 if (transferMod != null && sp != null)
252 {
253 if (message != null)
254 sp.ControllingClient.SendAgentAlertMessage(message, true);
255
249 transferMod.DoTeleport( 256 transferMod.DoTeleport(
250 sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), 257 sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f),
251 Vector3.UnitX, teleportflags); 258 Vector3.UnitX, teleportflags);
259 }
260 }
261 else
262 {
263 m_log.InfoFormat("[HG LURE MODULE]: Lure failed: {0}", message);
264 client.SendAgentAlertMessage(message, true);
252 } 265 }
253 } 266 }
254 } 267 }
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
index 7177d9b..bea2834 100644
--- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
@@ -46,8 +46,12 @@ using OpenSim.Region.Framework.Scenes;
46using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
47using Mono.Addins; 47using Mono.Addins;
48using OpenSim.Services.Connectors.Hypergrid; 48using OpenSim.Services.Connectors.Hypergrid;
49using OpenSim.Framework.Servers.HttpServer;
50using OpenSim.Services.UserProfilesService;
51using GridRegion = OpenSim.Services.Interfaces.GridRegion;
52using Microsoft.CSharp;
49 53
50namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles 54namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
51{ 55{
52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserProfilesModule")] 56 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserProfilesModule")]
53 public class UserProfileModule : IProfileModule, INonSharedRegionModule 57 public class UserProfileModule : IProfileModule, INonSharedRegionModule
@@ -63,6 +67,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
63 Dictionary<UUID, UUID> m_classifiedCache = new Dictionary<UUID, UUID>(); 67 Dictionary<UUID, UUID> m_classifiedCache = new Dictionary<UUID, UUID>();
64 Dictionary<UUID, int> m_classifiedInterest = new Dictionary<UUID, int>(); 68 Dictionary<UUID, int> m_classifiedInterest = new Dictionary<UUID, int>();
65 69
70 private JsonRpcRequestManager rpc = new JsonRpcRequestManager();
71
66 public Scene Scene 72 public Scene Scene
67 { 73 {
68 get; private set; 74 get; private set;
@@ -74,7 +80,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
74 /// <value> 80 /// <value>
75 /// The configuration 81 /// The configuration
76 /// </value> 82 /// </value>
77 public IConfigSource Config { 83 public IConfigSource Config
84 {
78 get; 85 get;
79 set; 86 set;
80 } 87 }
@@ -85,7 +92,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
85 /// <value> 92 /// <value>
86 /// The profile server URI. 93 /// The profile server URI.
87 /// </value> 94 /// </value>
88 public string ProfileServerUri { 95 public string ProfileServerUri
96 {
89 get; 97 get;
90 set; 98 set;
91 } 99 }
@@ -107,11 +115,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
107 /// <value> 115 /// <value>
108 /// <c>true</c> if enabled; otherwise, <c>false</c>. 116 /// <c>true</c> if enabled; otherwise, <c>false</c>.
109 /// </value> 117 /// </value>
110 public bool Enabled { 118 public bool Enabled
119 {
111 get; 120 get;
112 set; 121 set;
113 } 122 }
114 123
124 public string MyGatekeeper
125 {
126 get; private set;
127 }
128
129
115 #region IRegionModuleBase implementation 130 #region IRegionModuleBase implementation
116 /// <summary> 131 /// <summary>
117 /// This is called to initialize the region module. For shared modules, this is called exactly once, after 132 /// This is called to initialize the region module. For shared modules, this is called exactly once, after
@@ -147,6 +162,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
147 m_log.Debug("[PROFILES]: Full Profiles Enabled"); 162 m_log.Debug("[PROFILES]: Full Profiles Enabled");
148 ReplaceableInterface = null; 163 ReplaceableInterface = null;
149 Enabled = true; 164 Enabled = true;
165
166 MyGatekeeper = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI",
167 new string[] { "Startup", "Hypergrid", "UserProfiles" }, String.Empty);
150 } 168 }
151 169
152 /// <summary> 170 /// <summary>
@@ -176,7 +194,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
176 Util.FireAndForget(delegate 194 Util.FireAndForget(delegate
177 { 195 {
178 GetImageAssets(((IScenePresence)obj).UUID); 196 GetImageAssets(((IScenePresence)obj).UUID);
179 }); 197 }, null, "UserProfileModule.GetImageAssets");
180 } 198 }
181 199
182 /// <summary> 200 /// <summary>
@@ -315,7 +333,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
315 UUID.TryParse(args[0], out creatorId); 333 UUID.TryParse(args[0], out creatorId);
316 parameters.Add("creatorId", OSD.FromUUID(creatorId)); 334 parameters.Add("creatorId", OSD.FromUUID(creatorId));
317 OSD Params = (OSD)parameters; 335 OSD Params = (OSD)parameters;
318 if(!JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString())) 336 if(!rpc.JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString()))
319 { 337 {
320 remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds); 338 remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds);
321 return; 339 return;
@@ -375,7 +393,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
375 GetUserProfileServerURI(target, out serverURI); 393 GetUserProfileServerURI(target, out serverURI);
376 394
377 object Ad = (object)ad; 395 object Ad = (object)ad;
378 if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString())) 396 if(!rpc.JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString()))
379 { 397 {
380 remoteClient.SendAgentAlertMessage( 398 remoteClient.SendAgentAlertMessage(
381 "Error getting classified info", false); 399 "Error getting classified info", false);
@@ -435,9 +453,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
435 uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags, 453 uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags,
436 int queryclassifiedPrice, IClientAPI remoteClient) 454 int queryclassifiedPrice, IClientAPI remoteClient)
437 { 455 {
456 Scene s = (Scene)remoteClient.Scene;
457 IMoneyModule money = s.RequestModuleInterface<IMoneyModule>();
458
459 if (money != null)
460 {
461 if (!money.AmountCovered(remoteClient.AgentId, queryclassifiedPrice))
462 {
463 remoteClient.SendAgentAlertMessage("You do not have enough money to create requested classified.", false);
464 return;
465 }
466 money.ApplyCharge(remoteClient.AgentId, queryclassifiedPrice, MoneyTransactionType.ClassifiedCharge);
467 }
468
438 UserClassifiedAdd ad = new UserClassifiedAdd(); 469 UserClassifiedAdd ad = new UserClassifiedAdd();
439 470
440 Scene s = (Scene) remoteClient.Scene;
441 Vector3 pos = remoteClient.SceneAgent.AbsolutePosition; 471 Vector3 pos = remoteClient.SceneAgent.AbsolutePosition;
442 ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y); 472 ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y);
443 ScenePresence p = FindPresence(remoteClient.AgentId); 473 ScenePresence p = FindPresence(remoteClient.AgentId);
@@ -471,10 +501,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
471 501
472 OSD.SerializeMembers(Ad); 502 OSD.SerializeMembers(Ad);
473 503
474 if(!JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString())) 504 if(!rpc.JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString()))
475 { 505 {
476 remoteClient.SendAgentAlertMessage( 506 remoteClient.SendAgentAlertMessage(
477 "Error updating classified", false); 507 "Error updating classified", false);
508 return;
478 } 509 }
479 } 510 }
480 511
@@ -497,10 +528,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
497 UUID.TryParse(queryClassifiedID.ToString(), out classifiedId); 528 UUID.TryParse(queryClassifiedID.ToString(), out classifiedId);
498 parameters.Add("classifiedId", OSD.FromUUID(classifiedId)); 529 parameters.Add("classifiedId", OSD.FromUUID(classifiedId));
499 OSD Params = (OSD)parameters; 530 OSD Params = (OSD)parameters;
500 if(!JsonRpcRequest(ref Params, "classified_delete", serverURI, UUID.Random().ToString())) 531 if(!rpc.JsonRpcRequest(ref Params, "classified_delete", serverURI, UUID.Random().ToString()))
501 { 532 {
502 remoteClient.SendAgentAlertMessage( 533 remoteClient.SendAgentAlertMessage(
503 "Error classified delete", false); 534 "Error classified delete", false);
535 return;
504 } 536 }
505 537
506 parameters = (OSDMap)Params; 538 parameters = (OSDMap)Params;
@@ -547,7 +579,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
547 OSDMap parameters= new OSDMap(); 579 OSDMap parameters= new OSDMap();
548 parameters.Add("creatorId", OSD.FromUUID(targetId)); 580 parameters.Add("creatorId", OSD.FromUUID(targetId));
549 OSD Params = (OSD)parameters; 581 OSD Params = (OSD)parameters;
550 if(!JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString())) 582 if(!rpc.JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString()))
551 { 583 {
552 remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks); 584 remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks);
553 return; 585 return;
@@ -588,37 +620,66 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
588 return; 620 return;
589 621
590 UUID targetID; 622 UUID targetID;
591 UUID.TryParse(args[0], out targetID); 623 UUID.TryParse (args [0], out targetID);
592 string serverURI = string.Empty; 624 string serverURI = string.Empty;
593 GetUserProfileServerURI(targetID, out serverURI); 625 GetUserProfileServerURI (targetID, out serverURI);
626
627 string theirGatekeeperURI;
628 GetUserGatekeeperURI (targetID, out theirGatekeeperURI);
629
594 IClientAPI remoteClient = (IClientAPI)sender; 630 IClientAPI remoteClient = (IClientAPI)sender;
595 631
596 UserProfilePick pick = new UserProfilePick(); 632 UserProfilePick pick = new UserProfilePick ();
597 UUID.TryParse(args[0], out pick.CreatorId); 633 UUID.TryParse (args [0], out pick.CreatorId);
598 UUID.TryParse(args[1], out pick.PickId); 634 UUID.TryParse (args [1], out pick.PickId);
599 635
600 636
601 object Pick = (object)pick; 637 object Pick = (object)pick;
602 if(!JsonRpcRequest(ref Pick, "pickinforequest", serverURI, UUID.Random().ToString())) 638 if (!rpc.JsonRpcRequest (ref Pick, "pickinforequest", serverURI, UUID.Random ().ToString ())) {
603 { 639 remoteClient.SendAgentAlertMessage (
604 remoteClient.SendAgentAlertMessage(
605 "Error selecting pick", false); 640 "Error selecting pick", false);
641 return;
606 } 642 }
607 pick = (UserProfilePick) Pick; 643 pick = (UserProfilePick)Pick;
608 if(pick.SnapshotId == UUID.Zero) 644
645 Vector3 globalPos = new Vector3(Vector3.Zero);
646
647 // Smoke and mirrors
648 if (pick.Gatekeeper == MyGatekeeper)
609 { 649 {
610 // In case of a new UserPick, the data may not be ready and we would send wrong data, skip it... 650 Vector3.TryParse(pick.GlobalPos,out globalPos);
611 m_log.DebugFormat("[PROFILES]: PickInfoRequest: SnapshotID is {0}", UUID.Zero.ToString()); 651 }
612 return; 652 else
653 {
654 // Setup the illusion
655 string region = string.Format("{0} {1}",pick.Gatekeeper,pick.SimName);
656 GridRegion target = Scene.GridService.GetRegionByName(Scene.RegionInfo.ScopeID, region);
657
658 if(target == null)
659 {
660 // This is a dead or unreachable region
661 }
662 else
663 {
664 // Work our slight of hand
665 int x = target.RegionLocX;
666 int y = target.RegionLocY;
667
668 dynamic synthX = globalPos.X - (globalPos.X/Constants.RegionSize) * Constants.RegionSize;
669 synthX += x;
670 globalPos.X = synthX;
671
672 dynamic synthY = globalPos.Y - (globalPos.Y/Constants.RegionSize) * Constants.RegionSize;
673 synthY += y;
674 globalPos.Y = synthY;
675 }
613 } 676 }
614
615 Vector3 globalPos;
616 Vector3.TryParse(pick.GlobalPos,out globalPos);
617 677
618 m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString()); 678 m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString());
619 679
680 // Pull the rabbit out of the hat
620 remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name, 681 remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name,
621 pick.Desc,pick.SnapshotId,pick.User,pick.OriginalName,pick.SimName, 682 pick.Desc,pick.SnapshotId,pick.ParcelName,pick.OriginalName,pick.SimName,
622 globalPos,pick.SortOrder,pick.Enabled); 683 globalPos,pick.SortOrder,pick.Enabled);
623 } 684 }
624 685
@@ -653,9 +714,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
653 /// Enabled. 714 /// Enabled.
654 /// </param> 715 /// </param>
655 public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled) 716 public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled)
656 { 717 {
657 718 //TODO: See how this works with NPC, May need to test
658 m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString()); 719 m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString());
720
659 UserProfilePick pick = new UserProfilePick(); 721 UserProfilePick pick = new UserProfilePick();
660 string serverURI = string.Empty; 722 string serverURI = string.Empty;
661 GetUserProfileServerURI(remoteClient.AgentId, out serverURI); 723 GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
@@ -667,40 +729,45 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
667 remoteClient.Scene.RegionInfo.WorldLocY + avaPos.Y, 729 remoteClient.Scene.RegionInfo.WorldLocY + avaPos.Y,
668 avaPos.Z); 730 avaPos.Z);
669 731
670 string landOwnerName = string.Empty; 732 string landParcelName = "My Parcel";
671 ILandObject land = p.Scene.LandChannel.GetLandObject(avaPos.X, avaPos.Y); 733 UUID landParcelID = p.currentParcelUUID;
672 if(land.LandData.IsGroupOwned) 734
735 ILandObject land = p.Scene.LandChannel.GetLandObject(avaPos.X, avaPos.Y);
736
737 if (land != null)
673 { 738 {
674 IGroupsModule groupMod = p.Scene.RequestModuleInterface<IGroupsModule>(); 739 // If land found, use parcel uuid from here because the value from SP will be blank if the avatar hasnt moved
675 UUID groupId = land.LandData.GroupID; 740 landParcelName = land.LandData.Name;
676 GroupRecord groupRecord = groupMod.GetGroupRecord(groupId); 741 landParcelID = land.LandData.GlobalID;
677 landOwnerName = groupRecord.GroupName;
678 } 742 }
679 else 743 else
680 { 744 {
681 IUserAccountService accounts = p.Scene.RequestModuleInterface<IUserAccountService>(); 745 m_log.WarnFormat(
682 UserAccount user = accounts.GetUserAccount(p.Scene.RegionInfo.ScopeID, land.LandData.OwnerID); 746 "[PROFILES]: PickInfoUpdate found no parcel info at {0},{1} in {2}",
683 landOwnerName = user.Name; 747 avaPos.X, avaPos.Y, p.Scene.Name);
684 } 748 }
685 749
750
686 pick.PickId = pickID; 751 pick.PickId = pickID;
687 pick.CreatorId = creatorID; 752 pick.CreatorId = creatorID;
688 pick.TopPick = topPick; 753 pick.TopPick = topPick;
689 pick.Name = name; 754 pick.Name = name;
690 pick.Desc = desc; 755 pick.Desc = desc;
691 pick.ParcelId = p.currentParcelUUID; 756 pick.ParcelId = landParcelID;
692 pick.SnapshotId = snapshotID; 757 pick.SnapshotId = snapshotID;
693 pick.User = landOwnerName; 758 pick.ParcelName = landParcelName;
694 pick.SimName = remoteClient.Scene.RegionInfo.RegionName; 759 pick.SimName = remoteClient.Scene.RegionInfo.RegionName;
760 pick.Gatekeeper = MyGatekeeper;
695 pick.GlobalPos = posGlobal.ToString(); 761 pick.GlobalPos = posGlobal.ToString();
696 pick.SortOrder = sortOrder; 762 pick.SortOrder = sortOrder;
697 pick.Enabled = enabled; 763 pick.Enabled = enabled;
698 764
699 object Pick = (object)pick; 765 object Pick = (object)pick;
700 if(!JsonRpcRequest(ref Pick, "picks_update", serverURI, UUID.Random().ToString())) 766 if(!rpc.JsonRpcRequest(ref Pick, "picks_update", serverURI, UUID.Random().ToString()))
701 { 767 {
702 remoteClient.SendAgentAlertMessage( 768 remoteClient.SendAgentAlertMessage(
703 "Error updating pick", false); 769 "Error updating pick", false);
770 return;
704 } 771 }
705 772
706 m_log.DebugFormat("[PROFILES]: Finish PickInfoUpdate {0} {1}", pick.Name, pick.PickId.ToString()); 773 m_log.DebugFormat("[PROFILES]: Finish PickInfoUpdate {0} {1}", pick.Name, pick.PickId.ToString());
@@ -723,10 +790,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
723 OSDMap parameters= new OSDMap(); 790 OSDMap parameters= new OSDMap();
724 parameters.Add("pickId", OSD.FromUUID(queryPickID)); 791 parameters.Add("pickId", OSD.FromUUID(queryPickID));
725 OSD Params = (OSD)parameters; 792 OSD Params = (OSD)parameters;
726 if(!JsonRpcRequest(ref Params, "picks_delete", serverURI, UUID.Random().ToString())) 793 if(!rpc.JsonRpcRequest(ref Params, "picks_delete", serverURI, UUID.Random().ToString()))
727 { 794 {
728 remoteClient.SendAgentAlertMessage( 795 remoteClient.SendAgentAlertMessage(
729 "Error picks delete", false); 796 "Error picks delete", false);
797 return;
730 } 798 }
731 } 799 }
732 #endregion Picks 800 #endregion Picks
@@ -758,7 +826,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
758 UUID.TryParse(args[0], out note.TargetId); 826 UUID.TryParse(args[0], out note.TargetId);
759 827
760 object Note = (object)note; 828 object Note = (object)note;
761 if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString())) 829 if(!rpc.JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString()))
762 { 830 {
763 remoteClient.SendAvatarNotesReply(note.TargetId, note.Notes); 831 remoteClient.SendAvatarNotesReply(note.TargetId, note.Notes);
764 return; 832 return;
@@ -792,13 +860,81 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
792 GetUserProfileServerURI(remoteClient.AgentId, out serverURI); 860 GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
793 861
794 object Note = note; 862 object Note = note;
795 if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString())) 863 if(!rpc.JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString()))
796 { 864 {
865 remoteClient.SendAgentAlertMessage(
866 "Error updating note", false);
797 return; 867 return;
798 } 868 }
799 } 869 }
800 #endregion Notes 870 #endregion Notes
801 871
872<<<<<<< HEAD
873 #region User Preferences
874 /// <summary>
875 /// Updates the user preferences.
876 /// </summary>
877 /// <param name='imViaEmail'>
878 /// Im via email.
879 /// </param>
880 /// <param name='visible'>
881 /// Visible.
882 /// </param>
883 /// <param name='remoteClient'>
884 /// Remote client.
885 /// </param>
886 public void UpdateUserPreferences(bool imViaEmail, bool visible, IClientAPI remoteClient)
887 {
888 UserPreferences pref = new UserPreferences();
889
890 pref.UserId = remoteClient.AgentId;
891 pref.IMViaEmail = imViaEmail;
892 pref.Visible = visible;
893
894 string serverURI = string.Empty;
895 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
896
897 object Pref = pref;
898 if(!rpc.JsonRpcRequest(ref Pref, "user_preferences_update", serverURI, UUID.Random().ToString()))
899 {
900 m_log.InfoFormat("[PROFILES]: UserPreferences update error");
901 remoteClient.SendAgentAlertMessage("Error updating preferences", false);
902 return;
903 }
904 }
905
906 /// <summary>
907 /// Users the preferences request.
908 /// </summary>
909 /// <param name='remoteClient'>
910 /// Remote client.
911 /// </param>
912 public void UserPreferencesRequest(IClientAPI remoteClient)
913 {
914 UserPreferences pref = new UserPreferences();
915
916 pref.UserId = remoteClient.AgentId;
917
918 string serverURI = string.Empty;
919 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
920
921
922 object Pref = (object)pref;
923 if(!rpc.JsonRpcRequest(ref Pref, "user_preferences_request", serverURI, UUID.Random().ToString()))
924 {
925// m_log.InfoFormat("[PROFILES]: UserPreferences request error");
926// remoteClient.SendAgentAlertMessage("Error requesting preferences", false);
927 return;
928 }
929 pref = (UserPreferences) Pref;
930
931 remoteClient.SendUserInfoReply(pref.IMViaEmail, pref.Visible, pref.EMail);
932
933 }
934 #endregion User Preferences
935
936=======
937>>>>>>> avn/ubitvar
802 #region Avatar Properties 938 #region Avatar Properties
803 /// <summary> 939 /// <summary>
804 /// Update the avatars interests . 940 /// Update the avatars interests .
@@ -836,16 +972,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
836 GetUserProfileServerURI(remoteClient.AgentId, out serverURI); 972 GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
837 973
838 object Param = prop; 974 object Param = prop;
839 if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString())) 975 if(!rpc.JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString()))
840 { 976 {
841 remoteClient.SendAgentAlertMessage( 977 remoteClient.SendAgentAlertMessage(
842 "Error updating interests", false); 978 "Error updating interests", false);
979 return;
843 } 980 }
844 } 981 }
845 982
846 public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 983 public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
847 { 984 {
848 if ( String.IsNullOrEmpty(avatarID.ToString()) || String.IsNullOrEmpty(remoteClient.AgentId.ToString())) 985 if (String.IsNullOrEmpty(avatarID.ToString()) || String.IsNullOrEmpty(remoteClient.AgentId.ToString()))
849 { 986 {
850 // Looking for a reason that some viewers are sending null Id's 987 // Looking for a reason that some viewers are sending null Id's
851 m_log.DebugFormat("[PROFILES]: This should not happen remoteClient.AgentId {0} - avatarID {1}", remoteClient.AgentId, avatarID); 988 m_log.DebugFormat("[PROFILES]: This should not happen remoteClient.AgentId {0} - avatarID {1}", remoteClient.AgentId, avatarID);
@@ -922,7 +1059,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
922 string result = string.Empty; 1059 string result = string.Empty;
923 1060
924 props.UserId = avatarID; 1061 props.UserId = avatarID;
925 GetProfileData(ref props, out result); 1062
1063 if (!GetProfileData(ref props, foreign, out result))
1064 {
1065// m_log.DebugFormat("Error getting profile for {0}: {1}", avatarID, result);
1066 return;
1067 }
926 1068
927 remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, charterMember , props.FirstLifeText, flags, 1069 remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, charterMember , props.FirstLifeText, flags,
928 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); 1070 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId);
@@ -959,10 +1101,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
959 1101
960 object Prop = prop; 1102 object Prop = prop;
961 1103
962 if(!JsonRpcRequest(ref Prop, "avatar_properties_update", serverURI, UUID.Random().ToString())) 1104 if(!rpc.JsonRpcRequest(ref Prop, "avatar_properties_update", serverURI, UUID.Random().ToString()))
963 { 1105 {
964 remoteClient.SendAgentAlertMessage( 1106 remoteClient.SendAgentAlertMessage(
965 "Error updating properties", false); 1107 "Error updating properties", false);
1108 return;
966 } 1109 }
967 1110
968 RequestAvatarProperties(remoteClient, newProfile.ID); 1111 RequestAvatarProperties(remoteClient, newProfile.ID);
@@ -975,10 +1118,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
975 /// <returns> 1118 /// <returns>
976 /// The profile data. 1119 /// The profile data.
977 /// </returns> 1120 /// </returns>
978 /// <param name='userID'> 1121 bool GetProfileData(ref UserProfileProperties properties, bool foreign, out string message)
979 /// User I.
980 /// </param>
981 bool GetProfileData(ref UserProfileProperties properties, out string message)
982 { 1122 {
983 // Can't handle NPC yet... 1123 // Can't handle NPC yet...
984 ScenePresence p = FindPresence(properties.UserId); 1124 ScenePresence p = FindPresence(properties.UserId);
@@ -997,14 +1137,49 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
997 1137
998 // This is checking a friend on the home grid 1138 // This is checking a friend on the home grid
999 // Not HG friend 1139 // Not HG friend
1000 if ( String.IsNullOrEmpty(serverURI)) 1140 if (String.IsNullOrEmpty(serverURI))
1001 { 1141 {
1002 message = "No Presence - foreign friend"; 1142 message = "No Presence - foreign friend";
1003 return false; 1143 return false;
1004 } 1144 }
1005 1145
1006 object Prop = (object)properties; 1146 object Prop = (object)properties;
1007 JsonRpcRequest(ref Prop, "avatar_properties_request", serverURI, UUID.Random().ToString()); 1147 if (!rpc.JsonRpcRequest(ref Prop, "avatar_properties_request", serverURI, UUID.Random().ToString()))
1148 {
1149 // If it's a foreign user then try again using OpenProfile, in case that's what the grid is using
1150 bool secondChanceSuccess = false;
1151 if (foreign)
1152 {
1153 try
1154 {
1155 OpenProfileClient client = new OpenProfileClient(serverURI);
1156 if (client.RequestAvatarPropertiesUsingOpenProfile(ref properties))
1157 secondChanceSuccess = true;
1158 }
1159 catch (Exception e)
1160 {
1161 m_log.Debug(
1162 string.Format(
1163 "[PROFILES]: Request using the OpenProfile API for user {0} to {1} failed",
1164 properties.UserId, serverURI),
1165 e);
1166
1167 // Allow the return 'message' to say "JsonRpcRequest" and not "OpenProfile", because
1168 // the most likely reason that OpenProfile failed is that the remote server
1169 // doesn't support OpenProfile, and that's not very interesting.
1170 }
1171 }
1172
1173 if (!secondChanceSuccess)
1174 {
1175 message = string.Format("JsonRpcRequest for user {0} to {1} failed", properties.UserId, serverURI);
1176 m_log.DebugFormat("[PROFILES]: {0}", message);
1177
1178 return false;
1179 }
1180 // else, continue below
1181 }
1182
1008 properties = (UserProfileProperties)Prop; 1183 properties = (UserProfileProperties)Prop;
1009 1184
1010 message = "Success"; 1185 message = "Success";
@@ -1025,25 +1200,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
1025 1200
1026 assetServerURI = UserManagementModule.GetUserServerURL(avatarId, "AssetServerURI"); 1201 assetServerURI = UserManagementModule.GetUserServerURL(avatarId, "AssetServerURI");
1027 1202
1203 if(string.IsNullOrEmpty(profileServerURI) || string.IsNullOrEmpty(assetServerURI))
1204 return false;
1205
1028 OSDMap parameters= new OSDMap(); 1206 OSDMap parameters= new OSDMap();
1029 parameters.Add("avatarId", OSD.FromUUID(avatarId)); 1207 parameters.Add("avatarId", OSD.FromUUID(avatarId));
1030 OSD Params = (OSD)parameters; 1208 OSD Params = (OSD)parameters;
1031 if(!JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString())) 1209 if(!rpc.JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString()))
1032 { 1210 {
1033 return false; 1211 return false;
1034 } 1212 }
1035 1213
1036 parameters = (OSDMap)Params; 1214 parameters = (OSDMap)Params;
1037 1215
1038 OSDArray list = (OSDArray)parameters["result"]; 1216 if (parameters.ContainsKey("result"))
1039
1040 foreach(OSD asset in list)
1041 { 1217 {
1042 OSDString assetId = (OSDString)asset; 1218 OSDArray list = (OSDArray)parameters["result"];
1219
1220 foreach (OSD asset in list)
1221 {
1222 OSDString assetId = (OSDString)asset;
1043 1223
1044 Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString())); 1224 Scene.AssetService.Get(string.Format("{0}/{1}", assetServerURI, assetId.AsString()));
1225 }
1226 return true;
1227 }
1228 else
1229 {
1230 m_log.ErrorFormat("[PROFILES]: Problematic response for image_assets_request from {0}", profileServerURI);
1231 return false;
1045 } 1232 }
1046 return true;
1047 } 1233 }
1048 1234
1049 /// <summary> 1235 /// <summary>
@@ -1097,7 +1283,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
1097 1283
1098 UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url); 1284 UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url);
1099 1285
1100 Dictionary<string, object> account = uConn.GetUserInfo(userID); 1286 Dictionary<string, object> account;
1287 try
1288 {
1289 account = uConn.GetUserInfo(userID);
1290 }
1291 catch (Exception e)
1292 {
1293 m_log.Debug("[PROFILES]: GetUserInfo call failed ", e);
1294 account = new Dictionary<string, object>();
1295 }
1101 1296
1102 if (account.Count > 0) 1297 if (account.Count > 0)
1103 { 1298 {
@@ -1125,6 +1320,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
1125 } 1320 }
1126 1321
1127 /// <summary> 1322 /// <summary>
1323 /// Gets the user gatekeeper server URI.
1324 /// </summary>
1325 /// <returns>
1326 /// The user gatekeeper server URI.
1327 /// </returns>
1328 /// <param name='userID'>
1329 /// If set to <c>true</c> user URI.
1330 /// </param>
1331 /// <param name='serverURI'>
1332 /// If set to <c>true</c> server URI.
1333 /// </param>
1334 bool GetUserGatekeeperURI(UUID userID, out string serverURI)
1335 {
1336 bool local;
1337 local = UserManagementModule.IsLocalGridUser(userID);
1338
1339 if (!local)
1340 {
1341 serverURI = UserManagementModule.GetUserServerURL(userID, "GatekeeperURI");
1342 // Is Foreign
1343 return true;
1344 }
1345 else
1346 {
1347 serverURI = MyGatekeeper;
1348 // Is local
1349 return false;
1350 }
1351 }
1352
1353 /// <summary>
1128 /// Gets the user profile server UR. 1354 /// Gets the user profile server UR.
1129 /// </summary> 1355 /// </summary>
1130 /// <returns> 1356 /// <returns>
@@ -1175,6 +1401,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
1175 return null; 1401 return null;
1176 } 1402 }
1177 #endregion Util 1403 #endregion Util
1404<<<<<<< HEAD
1405=======
1178 1406
1179 #region Web Util 1407 #region Web Util
1180 /// <summary> 1408 /// <summary>
@@ -1352,5 +1580,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
1352 return true; 1580 return true;
1353 } 1581 }
1354 #endregion Web Util 1582 #endregion Web Util
1583>>>>>>> avn/ubitvar
1355 } 1584 }
1356} 1585}