From 50945dd56029a1280c581ea9b29213ab0e162a0a Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 11 Aug 2011 21:43:26 +0100
Subject: add regression test for osNpcCreate when cloning an in-region avatar

---
 OpenSim/Region/Framework/Interfaces/INPCModule.cs  |  4 +-
 .../Region/OptionalModules/World/NPC/NPCModule.cs  | 29 +-------
 .../World/NPC/Tests/NPCModuleTests.cs              | 10 +--
 .../Shared/Api/Implementation/OSSL_Api.cs          |  6 +-
 .../Shared/Tests/OSSL_ApiAppearanceTest.cs         | 79 ++++++++++++++++++++--
 prebuild.xml                                       |  2 +
 6 files changed, 89 insertions(+), 41 deletions(-)

diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
index 08b973d..5e5c4a1 100644
--- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
@@ -40,9 +40,9 @@ namespace OpenSim.Region.Framework.Interfaces
         /// <param name="lastname"></param>
         /// <param name="position"></param>
         /// <param name="scene"></param>
-        /// <param name="cloneAppearanceFrom">The UUID of the avatar from which to clone the NPC's appearance from.</param>
+        /// <param name="appearance">The avatar appearance to use for the new NPC.</param>
         /// <returns>The UUID of the ScenePresence created.</returns>
-        UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom);
+        UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance);
 
         /// <summary>
         /// Check if the agent is an NPC.
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 580d7ef..c764c20 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -45,7 +45,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
         private Dictionary<UUID, NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>();
-        private Dictionary<UUID, AvatarAppearance> m_appearanceCache = new Dictionary<UUID, AvatarAppearance>();
 
         public void Initialise(Scene scene, IConfigSource source)
         {
@@ -124,28 +123,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
             }
         }
 
-        private AvatarAppearance GetAppearance(UUID target, Scene scene)
-        {
-            if (m_appearanceCache.ContainsKey(target))
-                return m_appearanceCache[target];
-
-            ScenePresence originalPresence = scene.GetScenePresence(target);
-
-            if (originalPresence != null)
-            {
-                AvatarAppearance originalAppearance = originalPresence.Appearance;
-                m_appearanceCache.Add(target, originalAppearance);
-                return originalAppearance;
-            }
-            else
-            {
-                m_log.DebugFormat(
-                    "[NPC MODULE]: Avatar {0} is not in the scene for us to grab baked textures from them.  Using defaults.", target);
-
-                return new AvatarAppearance();
-            }
-        }
-
         public bool IsNPC(UUID agentId, Scene scene)
         {
             ScenePresence sp = scene.GetScenePresence(agentId);
@@ -176,7 +153,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
             return true;
         }
 
-        public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom)
+        public UUID CreateNPC(
+            string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance)
         {
             NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene);
             npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
@@ -191,8 +169,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
             acd.lastname = lastname;
             acd.ServiceURLs = new Dictionary<string, object>();
 
-            AvatarAppearance originalAppearance = GetAppearance(cloneAppearanceFrom, scene);
-            AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true);
+            AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
             acd.Appearance = npcAppearance;
 
 //            for (int i = 0; i < acd.Appearance.Texture.FaceTextures.Length; i++)
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 2742b67..f8afc5a 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -59,7 +59,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
             AvatarFactoryModule afm = new AvatarFactoryModule();
             TestScene scene = SceneHelpers.SetupScene();
             SceneHelpers.SetupSceneModules(scene, config, afm, new NPCModule());
-            IClientAPI originalClient = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)).ControllingClient;
+            ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
 //            ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
 
             // 8 is the index of the first baked texture in AvatarAppearance
@@ -72,10 +72,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
             // ScenePresence.SendInitialData() to reset our entire appearance.
             scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId));
 
-            afm.SetAppearanceFromClient(originalClient, originalTe, null);
+            afm.SetAppearanceFromClient(sp.ControllingClient, originalTe, null);
 
             INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
-            UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId);
+            UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance);
 
             ScenePresence npc = scene.GetScenePresence(npcId);
 
@@ -96,12 +96,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
 
             TestScene scene = SceneHelpers.SetupScene();
             SceneHelpers.SetupSceneModules(scene, config, new NPCModule());
-            IClientAPI originalClient = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)).ControllingClient;
+            ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
 //            ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
 
             Vector3 startPos = new Vector3(128, 128, 30);
             INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
-            UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, originalClient.AgentId);
+            UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, sp.Appearance);
 
             ScenePresence npc = scene.GetScenePresence(npcId);
             Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 91ac3b7..b18aa3b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2135,11 +2135,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             INPCModule module = World.RequestModuleInterface<INPCModule>();
             if (module != null)
             {
+                ScenePresence clonePresence = World.GetScenePresence(new UUID(cloneFrom.m_string));
+                if (clonePresence == null)
+                    return new LSL_Key(UUID.Zero.ToString());
+
                 UUID x = module.CreateNPC(firstname,
                                           lastname,
                                           new Vector3((float) position.x, (float) position.y, (float) position.z),
                                           World,
-                                          new UUID(cloneFrom));
+                                          clonePresence.Appearance);
 
                 return new LSL_Key(x.ToString());
             }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
index 2218a1f..7f778d7 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -27,7 +27,9 @@
 
 using System;
 using System.Collections.Generic;
+using System.Reflection;
 using System.Text;
+using log4net;
 using Nini.Config;
 using NUnit.Framework;
 using OpenMetaverse;
@@ -35,6 +37,7 @@ using OpenMetaverse.Assets;
 using OpenMetaverse.StructuredData;
 using OpenSim.Framework;
 using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
+using OpenSim.Region.OptionalModules.World.NPC;
 using OpenSim.Region.Framework.Scenes;
 using OpenSim.Region.ScriptEngine.Shared;
 using OpenSim.Region.ScriptEngine.Shared.Api;
@@ -61,9 +64,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
             config.Set("Enabled", "true");
             config.Set("AllowOSFunctions", "true");
             config.Set("OSFunctionThreatLevel", "Severe");
+            config = initConfigSource.AddConfig("NPC");
+            config.Set("Enabled", "true");
 
             m_scene = SceneHelpers.SetupScene();
-            SceneHelpers.SetupSceneModules(m_scene, new AvatarFactoryModule());
+            SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule());
 
             m_engine = new XEngine.XEngine();
             m_engine.Initialise(initConfigSource);
@@ -73,12 +78,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
         /// <summary>
         /// Test creation of an NPC where the appearance data comes from a notecard
         /// </summary>
-//        [Test]
-//        public void TestOsNpcCreateFromNotecard()
-//        {
-//            TestHelpers.InMethod();
-////            log4net.Config.XmlConfigurator.Configure();
-//        }
+        //[Test]
+        public void TestOsNpcCreateFromNotecard()
+        {
+            TestHelpers.InMethod();
+            log4net.Config.XmlConfigurator.Configure();
+
+            // Store an avatar with a different height from default in a notecard.
+            UUID userId = TestHelpers.ParseTail(0x1);
+            float newHeight = 1.9f;
+
+            ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
+            sp.Appearance.AvatarHeight = newHeight;
+            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
+            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.osOwnerSaveAppearance(notecardName);
+
+            // Try creating a bot using the appearance in the notecard.
+            string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName);
+            Assert.That(npcRaw, Is.Not.Null);
+
+            UUID npcId = new UUID(npcRaw);
+            ScenePresence npc = m_scene.GetScenePresence(npcId);
+            Assert.That(npc, Is.Not.Null);
+            Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
+        }
+
+        /// <summary>
+        /// Test creation of an NPC where the appearance data comes from an avatar already in the region.
+        /// </summary>
+        [Test]
+        public void TestOsNpcCreateFromAvatar()
+        {
+            TestHelpers.InMethod();
+//            log4net.Config.XmlConfigurator.Configure();
+
+            // Store an avatar with a different height from default in a notecard.
+            UUID userId = TestHelpers.ParseTail(0x1);
+            float newHeight = 1.9f;
+
+            ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
+            sp.Appearance.AvatarHeight = newHeight;
+            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
+            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.osOwnerSaveAppearance(notecardName);
+
+            // Try creating a bot using the existing avatar's appearance
+            string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), sp.UUID.ToString());
+            Assert.That(npcRaw, Is.Not.Null);
+
+            UUID npcId = new UUID(npcRaw);
+            ScenePresence npc = m_scene.GetScenePresence(npcId);
+            Assert.That(npc, Is.Not.Null);
+            Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
+        }
 
         [Test]
         public void TestOsOwnerSaveAppearance()
diff --git a/prebuild.xml b/prebuild.xml
index dff54a3..411ceb0 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -3143,11 +3143,13 @@
       <Reference name="OpenSim.Framework.Communications"/>
       <Reference name="OpenSim.Region.CoreModules"/>
       <Reference name="OpenSim.Region.Framework"/>
+      <Reference name="OpenSim.Region.OptionalModules"/>
       <Reference name="OpenSim.Region.ScriptEngine.Shared"/>
       <Reference name="OpenSim.Region.ScriptEngine.Shared.Api"/>
       <Reference name="OpenSim.Region.ScriptEngine.XEngine"/>
       <Reference name="OpenSim.Services.Interfaces"/>
       <Reference name="OpenSim.Tests.Common"/>
+      <Reference name="log4net"/>
       <Reference name="nunit.framework" path="../../../bin/"/>
       <Reference name="Nini" path="../../../bin/"/>
       <Reference name="OpenMetaverse" path="../../../bin/"/>
-- 
cgit v1.1