/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the OpenSimulator Project nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System.Collections.Generic; using OpenMetaverse; using OpenMetaverse.StructuredData; using NUnit.Framework; using OpenSim.Tests.Common; namespace OpenSim.Framework.Tests { [TestFixture] public class AgentCircuitDataTest : OpenSimTestCase { private UUID AgentId; private AvatarAppearance AvAppearance; private byte[] VisualParams; private UUID BaseFolder; private string CapsPath; private Dictionary<ulong, string> ChildrenCapsPaths; private uint circuitcode = 0949030; private string firstname; private string lastname; private UUID SecureSessionId; private UUID SessionId; private Vector3 StartPos; [SetUp] public void setup() { AgentId = UUID.Random(); BaseFolder = UUID.Random(); CapsPath = "http://www.opensimulator.org/Caps/Foo"; ChildrenCapsPaths = new Dictionary<ulong, string>(); ChildrenCapsPaths.Add(ulong.MaxValue, "http://www.opensimulator.org/Caps/Foo2"); firstname = "CoolAvatarTest"; lastname = "test"; StartPos = new Vector3(5,23,125); SecureSessionId = UUID.Random(); SessionId = UUID.Random(); AvAppearance = new AvatarAppearance(); VisualParams = new byte[218]; //body VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEIGHT] = 155; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_THICKNESS] = 00; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BODY_FAT] = 0; //Torso VisualParams[(int)AvatarAppearance.VPElement.SHAPE_TORSO_MUSCLES] = 48; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_NECK_THICKNESS] = 43; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_NECK_LENGTH] = 255; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_SHOULDERS] = 94; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_CHEST_MALE_NO_PECS] = 199; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_ARM_LENGTH] = 255; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HAND_SIZE] = 33; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_TORSO_LENGTH] = 240; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_LOVE_HANDLES] = 0; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BELLY_SIZE] = 0; // legs VisualParams[(int)AvatarAppearance.VPElement.SHAPE_LEG_MUSCLES] = 82; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_LEG_LENGTH] = 255; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HIP_WIDTH] = 84; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HIP_LENGTH] = 166; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BUTT_SIZE] = 64; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_SADDLEBAGS] = 89; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BOWED_LEGS] = 127; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_FOOT_SIZE] = 45; // head VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEAD_SIZE] = 255; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_SQUASH_STRETCH_HEAD] = 0; // head stretch VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEAD_SHAPE] = 155; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_EGG_HEAD] = 127; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_POINTY_EARS] = 255; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEAD_LENGTH] = 45; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_FACE_SHEAR] = 127; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_FOREHEAD_ANGLE] = 104; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BIG_BROW] = 94; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_PUFFY_UPPER_CHEEKS] = 0; // upper cheeks VisualParams[(int)AvatarAppearance.VPElement.SHAPE_DOUBLE_CHIN] = 122; // lower cheeks VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HIGH_CHEEK_BONES] = 130; // eyes VisualParams[(int)AvatarAppearance.VPElement.SHAPE_EYE_SIZE] = 105; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_WIDE_EYES] = 135; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_EYE_SPACING] = 184; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_EYELID_CORNER_UP] = 230; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_EYELID_INNER_CORNER_UP] = 120; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_EYE_DEPTH] = 158; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_UPPER_EYELID_FOLD] = 69; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BAGGY_EYES] = 38; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_EYELASHES_LONG] = 127; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_POP_EYE] = 127; VisualParams[(int)AvatarAppearance.VPElement.EYES_EYE_COLOR] = 25; VisualParams[(int)AvatarAppearance.VPElement.EYES_EYE_LIGHTNESS] = 127; // ears VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BIG_EARS] = 255; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_EARS_OUT] = 127; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_ATTACHED_EARLOBES] = 127; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_POINTY_EARS] = 255; // nose VisualParams[(int)AvatarAppearance.VPElement.SHAPE_NOSE_BIG_OUT] = 79; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_WIDE_NOSE] = 35; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BROAD_NOSTRILS] = 86; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_LOW_SEPTUM_NOSE] = 112; // nostril division VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BULBOUS_NOSE] = 25; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_NOBLE_NOSE_BRIDGE] = 25; // upper bridge VisualParams[(int)AvatarAppearance.VPElement.SHAPE_LOWER_BRIDGE_NOSE] = 25; // lower bridge VisualParams[(int)AvatarAppearance.VPElement.SHAPE_WIDE_NOSE_BRIDGE] = 25; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_UPTURNED_NOSE_TIP] = 107; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_BULBOUS_NOSE_TIP] = 25; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_CROOKED_NOSE] = 127; // Mouth VisualParams[(int)AvatarAppearance.VPElement.SHAPE_LIP_WIDTH] = 122; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_TALL_LIPS] = 10; // lip fullness VisualParams[(int)AvatarAppearance.VPElement.SHAPE_LIP_THICKNESS] = 112; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_LIP_RATIO] = 137; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MOUTH_HEIGHT] = 176; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MOUTH_CORNER] = 140; // Sad --> happy VisualParams[(int)AvatarAppearance.VPElement.SHAPE_LIP_CLEFT_DEEP] = 84; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_WIDE_LIP_CLEFT] = 84; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_SHIFT_MOUTH] = 127; // chin VisualParams[(int)AvatarAppearance.VPElement.SHAPE_WEAK_CHIN] = 119; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_SQUARE_JAW] = 5; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_DEEP_CHIN] = 132; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_JAW_ANGLE] = 153; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_JAW_JUT] = 100; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_JOWLS] = 38; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_CLEFT_CHIN] = 89; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_CLEFT_CHIN_UPPER] = 89; VisualParams[(int)AvatarAppearance.VPElement.SHAPE_DOUBLE_CHIN] = 0; // hair color VisualParams[(int)AvatarAppearance.VPElement.HAIR_WHITE_HAIR] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_RAINBOW_COLOR_39] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_BLONDE_HAIR] = 24; VisualParams[(int)AvatarAppearance.VPElement.HAIR_RED_HAIR] = 0; // hair style VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_VOLUME] = 160; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_FRONT] = 153; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_SIDES] = 153; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_BACK] = 170; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_BIG_FRONT] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_BIG_TOP] = 117; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_BIG_BACK] = 170; VisualParams[(int)AvatarAppearance.VPElement.HAIR_FRONT_FRINGE] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_SIDE_FRINGE] = 142; VisualParams[(int)AvatarAppearance.VPElement.HAIR_BACK_FRINGE] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_SIDES_FULL] = 146; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_SWEEP] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_SHEAR_FRONT] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_SHEAR_BACK] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_TAPER_FRONT] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_TAPER_BACK] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_RUMPLED] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_PIGTAILS] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_PONYTAIL] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_SPIKED] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_TILT] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_PART_MIDDLE] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_PART_RIGHT] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_PART_LEFT] = 0; VisualParams[(int)AvatarAppearance.VPElement.HAIR_BANGS_PART_MIDDLE] = 155; //Eyebrows VisualParams[(int)AvatarAppearance.VPElement.HAIR_EYEBROW_SIZE] = 20; VisualParams[(int)AvatarAppearance.VPElement.HAIR_EYEBROW_DENSITY] = 140; VisualParams[(int)AvatarAppearance.VPElement.HAIR_LOWER_EYEBROWS] = 200; // eyebrow height VisualParams[(int)AvatarAppearance.VPElement.HAIR_ARCED_EYEBROWS] = 124; VisualParams[(int)AvatarAppearance.VPElement.HAIR_POINTY_EYEBROWS] = 65; //Facial hair VisualParams[(int)AvatarAppearance.VPElement.HAIR_HAIR_THICKNESS] = 65; VisualParams[(int)AvatarAppearance.VPElement.HAIR_SIDEBURNS] = 235; VisualParams[(int)AvatarAppearance.VPElement.HAIR_MOUSTACHE] = 75; VisualParams[(int)AvatarAppearance.VPElement.HAIR_CHIN_CURTAINS] = 140; VisualParams[(int)AvatarAppearance.VPElement.HAIR_SOULPATCH] = 0; AvAppearance.VisualParams = VisualParams; List<byte> wearbyte = new List<byte>(); for (int i = 0; i < VisualParams.Length; i++) { wearbyte.Add(VisualParams[i]); } AvAppearance.SetAppearance(AvAppearance.Texture, (byte[])VisualParams.Clone()); } /// <summary> /// Test to ensure that the serialization format is the same and the underlying types don't change without notice /// oldSerialization is just a json serialization of the OSDMap packed for the AgentCircuitData. /// The idea is that if the current json serializer cannot parse the old serialization, then the underlying types /// have changed and are incompatible. /// </summary> [Test] public void HistoricalAgentCircuitDataOSDConversion() { string oldSerialization = "{\"agent_id\":\"522675bd-8214-40c1-b3ca-9c7f7fd170be\",\"base_folder\":\"c40b5f5f-476f-496b-bd69-b5a539c434d8\",\"caps_path\":\"http://www.opensimulator.org/Caps/Foo\",\"children_seeds\":[{\"handle\":\"18446744073709551615\",\"seed\":\"http://www.opensimulator.org/Caps/Foo2\"}],\"child\":false,\"circuit_code\":\"949030\",\"first_name\":\"CoolAvatarTest\",\"last_name\":\"test\",\"inventory_folder\":\"c40b5f5f-476f-496b-bd69-b5a539c434d8\",\"secure_session_id\":\"1e608e2b-0ddb-41f6-be0f-926f61cd3e0a\",\"session_id\":\"aa06f798-9d70-4bdb-9bbf-012a02ee2baf\",\"start_pos\":\"<5, 23, 125>\"}"; AgentCircuitData Agent1Data = new AgentCircuitData(); Agent1Data.AgentID = new UUID("522675bd-8214-40c1-b3ca-9c7f7fd170be"); Agent1Data.Appearance = AvAppearance; Agent1Data.BaseFolder = new UUID("c40b5f5f-476f-496b-bd69-b5a539c434d8"); Agent1Data.CapsPath = CapsPath; Agent1Data.child = false; Agent1Data.ChildrenCapSeeds = ChildrenCapsPaths; Agent1Data.circuitcode = circuitcode; Agent1Data.firstname = firstname; Agent1Data.InventoryFolder = new UUID("c40b5f5f-476f-496b-bd69-b5a539c434d8"); Agent1Data.lastname = lastname; Agent1Data.SecureSessionID = new UUID("1e608e2b-0ddb-41f6-be0f-926f61cd3e0a"); Agent1Data.SessionID = new UUID("aa06f798-9d70-4bdb-9bbf-012a02ee2baf"); Agent1Data.startpos = StartPos; OSDMap map2; try { map2 = (OSDMap) OSDParser.DeserializeJson(oldSerialization); AgentCircuitData Agent2Data = new AgentCircuitData(); Agent2Data.UnpackAgentCircuitData(map2); Assert.That((Agent1Data.AgentID == Agent2Data.AgentID)); Assert.That((Agent1Data.BaseFolder == Agent2Data.BaseFolder)); Assert.That((Agent1Data.CapsPath == Agent2Data.CapsPath)); Assert.That((Agent1Data.child == Agent2Data.child)); Assert.That((Agent1Data.ChildrenCapSeeds.Count == Agent2Data.ChildrenCapSeeds.Count)); Assert.That((Agent1Data.circuitcode == Agent2Data.circuitcode)); Assert.That((Agent1Data.firstname == Agent2Data.firstname)); Assert.That((Agent1Data.InventoryFolder == Agent2Data.InventoryFolder)); Assert.That((Agent1Data.lastname == Agent2Data.lastname)); Assert.That((Agent1Data.SecureSessionID == Agent2Data.SecureSessionID)); Assert.That((Agent1Data.SessionID == Agent2Data.SessionID)); Assert.That((Agent1Data.startpos == Agent2Data.startpos)); } catch (LitJson.JsonException) { //intermittant litjson errors :P Assert.That(1 == 1); } /* Enable this once VisualParams go in the packing method for (int i=0;i<208;i++) Assert.That((Agent1Data.Appearance.VisualParams[i] == Agent2Data.Appearance.VisualParams[i])); */ } /// <summary> /// Test to ensure that the packing and unpacking methods work. /// </summary> [Test] public void TestAgentCircuitDataOSDConversion() { AgentCircuitData Agent1Data = new AgentCircuitData(); Agent1Data.AgentID = AgentId; Agent1Data.Appearance = AvAppearance; Agent1Data.BaseFolder = BaseFolder; Agent1Data.CapsPath = CapsPath; Agent1Data.child = false; Agent1Data.ChildrenCapSeeds = ChildrenCapsPaths; Agent1Data.circuitcode = circuitcode; Agent1Data.firstname = firstname; Agent1Data.InventoryFolder = BaseFolder; Agent1Data.lastname = lastname; Agent1Data.SecureSessionID = SecureSessionId; Agent1Data.SessionID = SessionId; Agent1Data.startpos = StartPos; OSDMap map2; OSDMap map = Agent1Data.PackAgentCircuitData(); try { string str = OSDParser.SerializeJsonString(map); //System.Console.WriteLine(str); map2 = (OSDMap) OSDParser.DeserializeJson(str); } catch (System.NullReferenceException) { //spurious litjson errors :P map2 = map; Assert.That(1==1); return; } AgentCircuitData Agent2Data = new AgentCircuitData(); Agent2Data.UnpackAgentCircuitData(map2); Assert.That((Agent1Data.AgentID == Agent2Data.AgentID)); Assert.That((Agent1Data.BaseFolder == Agent2Data.BaseFolder)); Assert.That((Agent1Data.CapsPath == Agent2Data.CapsPath)); Assert.That((Agent1Data.child == Agent2Data.child)); Assert.That((Agent1Data.ChildrenCapSeeds.Count == Agent2Data.ChildrenCapSeeds.Count)); Assert.That((Agent1Data.circuitcode == Agent2Data.circuitcode)); Assert.That((Agent1Data.firstname == Agent2Data.firstname)); Assert.That((Agent1Data.InventoryFolder == Agent2Data.InventoryFolder)); Assert.That((Agent1Data.lastname == Agent2Data.lastname)); Assert.That((Agent1Data.SecureSessionID == Agent2Data.SecureSessionID)); Assert.That((Agent1Data.SessionID == Agent2Data.SessionID)); Assert.That((Agent1Data.startpos == Agent2Data.startpos)); /* Enable this once VisualParams go in the packing method for (int i = 0; i < 208; i++) Assert.That((Agent1Data.Appearance.VisualParams[i] == Agent2Data.Appearance.VisualParams[i])); */ } } }