From b1ae930c6b8e7d985e2c148a4e18a59ac880dcbd Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 11 Aug 2011 22:26:47 +0100
Subject: Implement osAgentSaveAppearance() to save the appearance of an avatar
 in the region to a notecard

This is separate from osOwnerSaveAppearance() so that owner saves can be allowed without allowing arbitrary avatar saves
---
 .../Shared/Api/Implementation/OSSL_Api.cs          | 35 +++++++++++++++---
 .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs |  2 +-
 .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs   |  5 +++
 .../Shared/Tests/OSSL_ApiAppearanceTest.cs         | 41 ++++++++++++++++++++++
 4 files changed, 78 insertions(+), 5 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index b18aa3b..939602a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2165,7 +2165,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 
             if (npcModule != null)
             {
-                UUID npcId = new UUID(npc.m_string);
+                UUID npcId;
+                if (!UUID.TryParse(npc.m_string, out npcId))
+                    return new LSL_Key(UUID.Zero.ToString());
 
                 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
                     return new LSL_Key(UUID.Zero.ToString());
@@ -2273,14 +2275,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             return SaveAppearanceToNotecard(m_host.OwnerID, notecardName);
         }
 
-        protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecardName)
+        public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecardName)
+        {
+            CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance");
+
+            return SaveAppearanceToNotecard(avatarId, notecardName);
+        }
+
+        protected LSL_Key SaveAppearanceToNotecard(ScenePresence sp, string notecardName)
         {
             IAvatarFactory appearanceModule = World.RequestModuleInterface<IAvatarFactory>();
 
             if (appearanceModule != null)
             {
-                appearanceModule.SaveBakedTextures(m_host.OwnerID);
-                ScenePresence sp = m_host.ParentGroup.Scene.GetScenePresence(m_host.OwnerID);
+                appearanceModule.SaveBakedTextures(sp.UUID);
                 OSDMap appearancePacked = sp.Appearance.Pack();
 
                 TaskInventoryItem item
@@ -2293,6 +2301,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                 return new LSL_Key(UUID.Zero.ToString());
             }
         }
+
+        protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecardName)
+        {
+            ScenePresence sp = World.GetScenePresence(avatarId);
+
+            if (sp == null || sp.IsChildAgent)
+                return new LSL_Key(UUID.Zero.ToString());
+
+            return SaveAppearanceToNotecard(sp, notecardName);
+        }
+
+        protected LSL_Key SaveAppearanceToNotecard(LSL_Key rawAvatarId, string notecardName)
+        {
+            UUID avatarId;
+            if (!UUID.TryParse(rawAvatarId, out avatarId))
+                return new LSL_Key(UUID.Zero.ToString());
+
+            return SaveAppearanceToNotecard(avatarId, notecardName);
+        }
         
         /// <summary>
         /// Get current region's map texture UUID
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index f4a618b..88e1f15 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -168,7 +168,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
 
         LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules);
 
-
         key osNpcCreate(string user, string name, vector position, key cloneFrom);
         LSL_Key osNpcSaveAppearance(key npc, string notecardName);
         void osNpcLoadAppearance(key npc, string notecardNameOrUuid);
@@ -179,6 +178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
         void osNpcRemove(key npc);
 
         LSL_Key osOwnerSaveAppearance(string notecardName);
+        LSL_Key osAgentSaveAppearance(key agentId, string notecardName);
 
         key osGetMapTexture();
         key osGetRegionMapTexture(string regionName);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 84d61f4..4701736 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -523,6 +523,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
             return m_OSSL_Functions.osOwnerSaveAppearance(notecardName);
         }
 
+        public LSL_Key osAgentSaveAppearance(LSL_Key agentId, string notecardName)
+        {
+            return m_OSSL_Functions.osAgentSaveAppearance(agentId, notecardName);
+        }
+
         public OSSLPrim Prim;
 
         [Serializable]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
index 7f778d7..85cf507 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -184,5 +184,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
 
             Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight));
         }
+
+        [Test]
+        public void TestOsAgentSaveAppearance()
+        {
+            TestHelpers.InMethod();
+//            log4net.Config.XmlConfigurator.Configure();
+
+            UUID ownerId = TestHelpers.ParseTail(0x1);
+            UUID nonOwnerId = TestHelpers.ParseTail(0x2);
+            float newHeight = 1.9f;
+
+            ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, nonOwnerId);
+            sp.Appearance.AvatarHeight = newHeight;
+            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId);
+            SceneObjectPart part = so.RootPart;
+            m_scene.AddSceneObject(so);
+
+            OSSL_Api osslApi = new OSSL_Api();
+            osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
+
+            string notecardName = "appearanceNc";
+
+            osslApi.osAgentSaveAppearance(new LSL_Types.LSLString(nonOwnerId.ToString()), notecardName);
+
+            IList<TaskInventoryItem> items = part.Inventory.GetInventoryItems(notecardName);
+            Assert.That(items.Count, Is.EqualTo(1));
+
+            TaskInventoryItem ncItem = items[0];
+            Assert.That(ncItem.Name, Is.EqualTo(notecardName));
+
+            AssetBase ncAsset = m_scene.AssetService.Get(ncItem.AssetID.ToString());
+            Assert.That(ncAsset, Is.Not.Null);
+
+            AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data);
+            anc.Decode();
+            OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(anc.BodyText);
+            AvatarAppearance savedAppearance = new AvatarAppearance();
+            savedAppearance.Unpack(appearanceOsd);
+
+            Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight));
+        }
     }
 }
\ No newline at end of file
-- 
cgit v1.1