Contains the Avatar's Appearance and methods to manipulate the appearance.
Inheritance: Universe.Framework.Modules.IDataTransferable
 public AvatarAppearance GetAndEnsureAppearance(UUID principalID, string defaultUserAvatarArchive, out bool loadedArchive)
 {
     loadedArchive = false;
     AvatarAppearance avappearance = GetAppearance(principalID);
     if (avappearance == null)
     {
         //Create an appearance for the user if one doesn't exist
         if (defaultUserAvatarArchive != "")
         {
             AvatarArchive arch = m_ArchiveService.LoadAvatarArchive(defaultUserAvatarArchive, principalID);
             if (arch != null)
             {
                 avappearance = arch.Appearance;
                 SetAppearance(principalID, avappearance);
                 loadedArchive = true;
             }
         }
         if(avappearance == null)//Set as ruth
         {
             avappearance = new AvatarAppearance(principalID);
             SetAppearance(principalID, avappearance);
         }
     }
     return avappearance;
 }
        /// <summary>
        ///     Region side
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        protected OSDMap OnMessageReceived(OSDMap message)
        {
            //We need to check and see if this is an AgentStatusChange
            if (message.ContainsKey("Method") && message["Method"] == "UpdateAvatarAppearance")
            {
                var appearance = new AvatarAppearance(message["AgentID"], (OSDMap)message["Appearance"]);
                ISceneManager manager = m_registry.RequestModuleInterface<ISceneManager>();

                if (manager != null)
                {
                    foreach (IScene scene in manager.Scenes)
                    {
                        IScenePresence sp = scene.GetScenePresence(appearance.Owner);
                        if (sp != null && !sp.IsChildAgent)
                        {
                            var avappmodule = sp.RequestModuleInterface<IAvatarAppearanceModule>();
                            if (avappmodule != null)
                            {
                                avappmodule.Appearance = appearance;
                                avappmodule.SendAppearanceToAgent(sp);
                                avappmodule.SendAppearanceToAllOtherAgents();
                            }
                        }
                    }
                }
            }

            return null;
        }
        /// <summary>
        ///     Do everything required once a client completes its movement into a region and becomes
        ///     a root agent.
        /// </summary>
        /// <param name="agentid">Agent to send appearance for</param>
        /// <param name="app"></param>
        void HandleInitialAppearanceSend (UUID agentid, AvatarAppearance app)
        {
            IScenePresence sp = m_scene.GetScenePresence (agentid);
            if (sp == null) {
                MainConsole.Instance.WarnFormat (
                    "[AvatarFactory]: Agent {0} no longer in the scene to send appearance for.", agentid);
                return;
            }
            IAvatarAppearanceModule appearance = sp.RequestModuleInterface<IAvatarAppearanceModule> ();

            MainConsole.Instance.InfoFormat ("[AvatarFactory]: Handle initial appearance send for {0}", agentid);

            // This agent just became root. We are going to tell everyone about it.
            appearance.SendAvatarDataToAllAgents (true);
            appearance.SendAppearanceToAgent (sp);

            sp.ControllingClient.SendWearables (appearance.Appearance.Wearables, appearance.Appearance.Serial);

            // If the avatars baked textures are all in the cache, then we have a 
            // complete appearance... send it out, if not, then we'll send it when
            // the avatar finishes updating its appearance
            appearance.SendAppearanceToAllOtherAgents ();

            // This agent just became root. We are going to tell everyone about it. The process of
            // getting other avatars information was initiated in the constructor... don't do it 
            // again here... 
            appearance.SendAvatarDataToAllAgents (true);

            //Tell us about everyone else as well now that we are here
            appearance.SendOtherAgentsAppearanceToMe ();
        }
        /// <summary>
        ///     Sends an avatars appearance (only called by the TimeSender)
        /// </summary>
        /// <param name="agentid"></param>
        /// <param name="app"></param>
        void HandleAppearanceSend (UUID agentid, AvatarAppearance app)
        {
            IScenePresence sp = m_scene.GetScenePresence (agentid);
            if (sp == null) {
                MainConsole.Instance.WarnFormat (
                    "[AvatarFactory]: Agent {0} no longer in the scene to send appearance for.", agentid);
                return;
            }
            IAvatarAppearanceModule appearance = sp.RequestModuleInterface<IAvatarAppearanceModule> ();

            // MainConsole.Instance.WarnFormat("[AvatarFactory]: Handle appearance send for {0}", agentid);

            // Send the appearance to everyone in the scene
            appearance.SendAppearanceToAllOtherAgents ();

            // Send animations back to the avatar as well
            sp.Animator.SendAnimPack ();
        }
        /// <summary>
        ///     Saves a user's appearance
        /// </summary>
        /// <param name="agentid"></param>
        /// <param name="app"></param>
        void HandleAppearanceSave (UUID agentid, AvatarAppearance app)
        {
            IScenePresence sp = m_scene.GetScenePresence (agentid);
            if (sp == null)
                return;

            IAvatarAppearanceModule appearanceModule = sp.RequestModuleInterface<IAvatarAppearanceModule> ();

            AvatarAppearance appearance = appearanceModule != null
                                              ? appearanceModule.Appearance
                                              : app;

            m_scene.AvatarService.SetAppearance (agentid, appearance);
        }
        public void SetAppearance(UUID principalID, AvatarAppearance appearance)
        {
            if (m_doRemoteOnly)
            {
                DoRemotePostByURL("AvatarServerURI", principalID, appearance);
                return;
            }

            m_registry.RequestModuleInterface<ISimulationBase>().EventManager.FireGenericEventHandler("SetAppearance",
                                                                                                      new object[2]
                                                                                                          {
                                                                                                              principalID,
                                                                                                              appearance
                                                                                                          });
            m_Database.Store(principalID, appearance);
        }
 public AvatarAppearance(AvatarAppearance appearance)
     : this(appearance, true)
 {
 }
            public AvatarAppearanceModule (IScenePresence sp)
            {
                m_sp = sp;
                m_sp.Scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent;

                AgentCircuitData circuitInfo = sp.Scene.AuthenticateHandler.GetAgentCircuitData (sp.UUID);
                if (circuitInfo.CachedUserInfo != null)
                    Appearance = circuitInfo.CachedUserInfo.Appearance;
                if (Appearance == null)
                    Appearance = sp.Scene.AvatarService.GetAppearance (sp.UUID);
                if (Appearance == null) {
                    MainConsole.Instance.Debug ("[Scene]: No avatar appearance found for " + sp.Name);
                    Appearance = new AvatarAppearance (sp.UUID);
                }
                _updateMonitor = m_sp.Scene.RequestModuleInterface<IMonitorModule> ().GetMonitor<IAgentUpdateMonitor> (sp.Scene);
            }
        LSL_Key NpcCreate(
            string firstname, string lastname, LSL_Types.Vector3 position, string notecard, bool owned, bool senseAsAgent)
        {
            IBotManager manager = World.RequestModuleInterface<IBotManager>();
            if (manager != null)
            {
                MainConsole.Instance.DebugFormat ("Creating NPC: {0} {1}, Position: {2}, Appearence: {3}, Options: {4} {5}",
                    firstname, lastname, position, notecard, owned, senseAsAgent);

                // check for notecard or UUID for appearance...
                AvatarAppearance appearance = null;
                UUID appearanceId;
                UUID.TryParse (notecard, out appearanceId);

                if (appearanceId == UUID.Zero)
                {
                    // not a UUID so try for a notecard
                    string appearanceSerialized = LoadNotecard(notecard);

                    if (appearanceSerialized != null)
                    {
                        var appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
                        appearance = new AvatarAppearance();
                        appearance.Unpack(appearanceOsd);
                    }
                    else
                    {
                        OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard));
                    }
                }

                UUID ownerID = UUID.Zero;
                if (owned)
                    ownerID = m_host.OwnerID;

                var npcPosition = position.ToVector3();
                UUID newBotId;

                if (appearance == null)
                {
                    newBotId = manager.CreateAvatar (
                        firstname,
                        lastname,
                        World,
                        appearanceId,
                        ownerID,
                        npcPosition
                    );
                } else
                {
                    newBotId = manager.CreateAvatar (
                        firstname,
                        lastname,
                        World,
                        appearance,
                        ownerID,
                        npcPosition
                    );

                }
                return new LSL_Key(newBotId.ToString());
            }

            return new LSL_Key(UUID.Zero.ToString());
        }
        public void FixCurrentOutFitFolder(UUID user, ref AvatarAppearance avappearance)
        {
            InventoryFolderBase CurrentOutFitFolder = m_InventoryService.GetFolderForType(user, 0, FolderType.CurrentOutfit);
            if (CurrentOutFitFolder == null) return;
            List<InventoryItemBase> ic = m_InventoryService.GetFolderItems(user, CurrentOutFitFolder.ID);
            List<UUID> brokenLinks = new List<UUID>();
            List<UUID> OtherStuff = new List<UUID>();
            foreach (var i in ic)
            {
                InventoryItemBase linkedItem;
                if ((linkedItem = m_InventoryService.GetItem(user, i.AssetID)) == null)
                    brokenLinks.Add(i.ID);
                else if (linkedItem.ID == AvatarWearable.DEFAULT_EYES_ITEM ||
                         linkedItem.ID == AvatarWearable.DEFAULT_SHAPE_ITEM ||
                         linkedItem.ID == AvatarWearable.DEFAULT_HAIR_ITEM ||
                         linkedItem.ID == AvatarWearable.DEFAULT_PANTS_ITEM ||
                         linkedItem.ID == AvatarWearable.DEFAULT_SHIRT_ITEM ||
                         linkedItem.ID == AvatarWearable.DEFAULT_SKIN_ITEM)
                    brokenLinks.Add(i.ID); //Default item link, needs removed
                else if (!OtherStuff.Contains(i.AssetID))
                    OtherStuff.Add(i.AssetID);
            }

            for (int i = 0; i < avappearance.Wearables.Length; i++)
            {
                AvatarWearable wearable = avappearance.Wearables[i];
                for (int ii = 0; ii < wearable.Count; ii++)
                {
                    if (!OtherStuff.Contains(wearable[ii].ItemID))
                    {
                        InventoryItemBase linkedItem2;
                        if ((linkedItem2 = m_InventoryService.GetItem(user, wearable[ii].ItemID)) != null)
                        {
                            InventoryItemBase linkedItem3 = (InventoryItemBase) linkedItem2.Clone();
                            linkedItem3.AssetID = linkedItem2.ID;
                            linkedItem3.AssetType = (int) AssetType.Link;
                            linkedItem3.ID = UUID.Random();
                            linkedItem3.CurrentPermissions = linkedItem2.NextPermissions;
                            linkedItem3.EveryOnePermissions = linkedItem2.NextPermissions;
                            linkedItem3.Folder = CurrentOutFitFolder.ID;
                            m_InventoryService.AddItem(linkedItem3);
                        }
                        else
                        {
                            avappearance.Wearables[i] = AvatarWearable.DefaultWearables[i];
                        }
                    }
                }
            }

            List<UUID> items2UnAttach = new List<UUID>();
            foreach (KeyValuePair<int, List<AvatarAttachment>> attachmentSpot in avappearance.Attachments)
            {
                foreach (AvatarAttachment attachment in attachmentSpot.Value)
                {
                    if (!OtherStuff.Contains(attachment.ItemID))
                    {
                        InventoryItemBase linkedItem2;
                        if ((linkedItem2 = m_InventoryService.GetItem(user, attachment.ItemID)) != null)
                        {
                            InventoryItemBase linkedItem3 = (InventoryItemBase) linkedItem2.Clone();
                            linkedItem3.AssetID = linkedItem2.ID;
                            linkedItem3.AssetType = (int) AssetType.Link;
                            linkedItem3.ID = UUID.Random();
                            linkedItem3.CurrentPermissions = linkedItem2.NextPermissions;
                            linkedItem3.EveryOnePermissions = linkedItem2.NextPermissions;
                            linkedItem3.Folder = CurrentOutFitFolder.ID;
                            m_InventoryService.AddItem(linkedItem3);
                        }
                        else
                            items2UnAttach.Add(attachment.ItemID);
                    }
                }
            }

            foreach (UUID uuid in items2UnAttach)
            {
                avappearance.DetachAttachment(uuid);
            }

            if (brokenLinks.Count != 0)
                m_InventoryService.DeleteItems(user, brokenLinks);
        }
        public LoginResponse Login(UUID AgentID, string Name, string authType, string passwd, string startLocation,
                                   string clientVersion, string channel, string mac, string id0, IPEndPoint clientIP,
                                   Hashtable requestData)
        {
            LoginResponse response;
            UUID session = UUID.Random();
            UUID secureSession = UUID.Zero;

            // TODO: Make this check better
            //
            // Some TPV's now send their name in Channel instead of clientVersion
            // while others send a Channel and a clientVersion.

            string realViewer;

            if (channel != "")
            {
                realViewer = channel + " " + clientVersion;
            }
            else
            {
                realViewer = clientVersion;
            }

            MainConsole.Instance.InfoFormat(
                "[LLOGIN SERVICE]: Login request for {0} from {1} with user agent {2} starting in {3}",
                Name, clientIP.Address, realViewer, startLocation);

            UserAccount account = AgentID != UUID.Zero
                                      ? m_UserAccountService.GetUserAccount(null, AgentID)
                                      : m_UserAccountService.GetUserAccount(null, Name);
            if (account == null && m_AllowAnonymousLogin)
            {
                m_UserAccountService.CreateUser(Name, passwd.StartsWith("$1$") ? passwd.Remove(0, 3) : passwd, "");
                account = m_UserAccountService.GetUserAccount(null, Name);
            }
            if (account == null)
            {
                MainConsole.Instance.InfoFormat("[LLOGIN SERVICE]: Login failed for user {0}: no account found", Name);
                return LLFailedLoginResponse.AccountProblem;
            }

            if (account.UserLevel < 0) //No allowing anyone less than 0
            {
                MainConsole.Instance.InfoFormat(
                    "[LLOGIN SERVICE]: Login failed for user {0}, reason: user is banned",
                    account.Name);
                return LLFailedLoginResponse.PermanentBannedProblem;
            }

            if (account.UserLevel < m_MinLoginLevel)
            {
                MainConsole.Instance.InfoFormat(
                    "[LLOGIN SERVICE]: Login failed for user {1}, reason: login is blocked for user level {0}",
                    account.UserLevel, account.Name);
                return LLFailedLoginResponse.LoginBlockedProblem;
            }

            IAgentInfo agent = null;
            IAgentConnector agentData = Framework.Utilities.DataManager.RequestPlugin<IAgentConnector>();
            if (agentData != null)
                agent = agentData.GetAgent(account.PrincipalID);
            if (agent == null)
            {
                agentData.CreateNewAgent(account.PrincipalID);
                agent = agentData.GetAgent(account.PrincipalID);
            }

            requestData["ip"] = clientIP.ToString();
            foreach (ILoginModule module in LoginModules)
            {
                object data;
                if ((response = module.Login(requestData, account, agent, authType, passwd, out data)) != null)
                {
                    MainConsole.Instance.InfoFormat(
                        "[LLOGIN SERVICE]: Login failed for user {1}, reason: {0}",
                        (data != null ? data.ToString() : (response is LLFailedLoginResponse) ? (response as LLFailedLoginResponse).Value : "Unknown"), account.Name);
                    return response;
                }
                if (data != null)
                    secureSession = (UUID) data; //TODO: NEED TO FIND BETTER WAY TO GET THIS DATA
            }

            try
            {
                string DisplayName = account.Name;
                AvatarAppearance avappearance = null;
                IProfileConnector profileData = Framework.Utilities.DataManager.RequestPlugin<IProfileConnector>();

                //
                // Get the user's inventory
                //
                if (m_RequireInventory && m_InventoryService == null)
                {
                    MainConsole.Instance.WarnFormat(
                        "[LLOGIN SERVICE]: Login failed for user {0}, reason: inventory service not set up",
                        account.Name);
                    return LLFailedLoginResponse.InventoryProblem;
                }
                List<InventoryFolderBase> inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
                if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel.Count == 0)))
                {
                    List<InventoryItemBase> defaultItems;
                    m_InventoryService.CreateUserInventory(account.PrincipalID, m_DefaultUserAvatarArchive == "",
                                                           out defaultItems);
                    inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
                    if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel.Count == 0)))
                    {
                        MainConsole.Instance.InfoFormat(
                            "[LLOGIN SERVICE]: Login failed for user {0}, reason: unable to retrieve user inventory",
                            account.Name);
                        return LLFailedLoginResponse.InventoryProblem;
                    }
                    if (defaultItems.Count > 0)
                    {
                        avappearance = new AvatarAppearance(account.PrincipalID);
                        avappearance.SetWearable((int)WearableType.Shape,
                                                 new AvatarWearable(defaultItems[0].ID, defaultItems[0].AssetID));
                        avappearance.SetWearable((int)WearableType.Skin,
                                                 new AvatarWearable(defaultItems[1].ID, defaultItems[1].AssetID));
                        avappearance.SetWearable((int)WearableType.Hair,
                                                 new AvatarWearable(defaultItems[2].ID, defaultItems[2].AssetID));
                        avappearance.SetWearable((int)WearableType.Eyes,
                                                 new AvatarWearable(defaultItems[3].ID, defaultItems[3].AssetID));
                        avappearance.SetWearable((int)WearableType.Shirt,
                                                 new AvatarWearable(defaultItems[4].ID, defaultItems[4].AssetID));
                        avappearance.SetWearable((int)WearableType.Pants,
                                                 new AvatarWearable(defaultItems[5].ID, defaultItems[5].AssetID));
                        m_AvatarService.SetAppearance(account.PrincipalID, avappearance);
                    }
                }

                if (profileData != null)
                {
                    IUserProfileInfo UPI = profileData.GetUserProfile(account.PrincipalID);
                    if (UPI == null)
                    {
                        profileData.CreateNewProfile(account.PrincipalID);
                        UPI = profileData.GetUserProfile(account.PrincipalID);
                        UPI.AArchiveName = m_DefaultUserAvatarArchive;
                        UPI.IsNewUser = true;
                        //profileData.UpdateUserProfile(UPI); //It gets hit later by the next thing
                    }
                    //Find which is set, if any
                    string archiveName = (UPI.AArchiveName != "" && UPI.AArchiveName != " ")
                                             ? UPI.AArchiveName
                                             : m_DefaultUserAvatarArchive;
                    if (UPI.IsNewUser && archiveName != "")
                    {
                        AvatarArchive arch = m_ArchiveService.LoadAvatarArchive(archiveName, account.PrincipalID);
                        UPI.AArchiveName = "";
                        if (arch != null)
                        {
                            avappearance = arch.Appearance;
                            m_AvatarService.SetAppearance(account.PrincipalID, avappearance);
                            //Must reload this, as we created a new folder
                            inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
                        }
                    }
                    if (UPI.IsNewUser)
                    {
                        UPI.IsNewUser = false;
                        profileData.UpdateUserProfile(UPI);
                    }
                    if (UPI.DisplayName != "")
                        DisplayName = UPI.DisplayName;
                }

                // Get active gestures
                List<InventoryItemBase> gestures = m_InventoryService.GetActiveGestures(account.PrincipalID);
                //MainConsole.Instance.DebugFormat("[LLOGIN SERVICE]: {0} active gestures", gestures.Count);

                //Now get the logged in status, then below make sure to kill the previous agent if we crashed before
                UserInfo guinfo = m_agentInfoService.GetUserInfo(account.PrincipalID.ToString());
                //
                // Clear out any existing CAPS the user may have
                //
                if (m_CapsService != null)
                {
                    IAgentProcessing agentProcessor = m_registry.RequestModuleInterface<IAgentProcessing>();
                    if (agentProcessor != null)
                    {
                        IClientCapsService clientCaps = m_CapsService.GetClientCapsService(account.PrincipalID);
                        if (clientCaps != null)
                        {
                            IRegionClientCapsService rootRegionCaps = clientCaps.GetRootCapsService();
                            if (rootRegionCaps != null)
                                agentProcessor.LogoutAgent(rootRegionCaps, !m_AllowDuplicateLogin);
                        }
                    }
                    else
                        m_CapsService.RemoveCAPS(account.PrincipalID);
                }

                //
                // Change Online status and get the home region
                //
                GridRegion home = null;
                if (guinfo != null && (guinfo.HomeRegionID != UUID.Zero) && m_GridService != null)
                    home = m_GridService.GetRegionByUUID(account.AllScopeIDs, guinfo.HomeRegionID);

                if (guinfo == null || guinfo.HomeRegionID == UUID.Zero) //Give them a default home and last
                {
                    bool positionSet = false;
                    if (guinfo == null)
                        guinfo = new UserInfo {UserID = account.PrincipalID.ToString()};
                    GridRegion DefaultRegion = null, FallbackRegion = null, SafeRegion = null;
                    if (m_GridService != null)
                    {
                        if (m_DefaultHomeRegion != "")
                        {
                            DefaultRegion = m_GridService.GetRegionByName(account.AllScopeIDs, m_DefaultHomeRegion);
                            if (DefaultRegion != null)
                                guinfo.HomeRegionID = guinfo.CurrentRegionID = DefaultRegion.RegionID;
                            guinfo.HomePosition = guinfo.CurrentPosition = m_DefaultHomeRegionPos;
                            positionSet = true;
                        }
                        if (guinfo.HomeRegionID == UUID.Zero)
                        {
                            List<GridRegion> DefaultRegions = m_GridService.GetDefaultRegions(account.AllScopeIDs);
                            DefaultRegion = DefaultRegions.Count == 0 ? null : DefaultRegions[0];

                            if (DefaultRegion != null)
                                guinfo.HomeRegionID = guinfo.CurrentRegionID = DefaultRegion.RegionID;

                            if (guinfo.HomeRegionID == UUID.Zero)
                            {
                                List<GridRegion> Fallback = m_GridService.GetFallbackRegions(account.AllScopeIDs, 0, 0);
                                FallbackRegion = Fallback.Count == 0 ? null : Fallback[0];

                                if (FallbackRegion != null)
                                    guinfo.HomeRegionID = guinfo.CurrentRegionID = FallbackRegion.RegionID;

                                if (guinfo.HomeRegionID == UUID.Zero)
                                {
                                    List<GridRegion> Safe = m_GridService.GetSafeRegions(account.AllScopeIDs, 0, 0);
                                    SafeRegion = Safe.Count == 0 ? null : Safe[0];

                                    if (SafeRegion != null)
                                        guinfo.HomeRegionID = guinfo.CurrentRegionID = SafeRegion.RegionID;
                                }
                            }
                        }
                    }

                    if(!positionSet)
                        guinfo.CurrentPosition = guinfo.HomePosition = new Vector3(128, 128, 25);
                    guinfo.HomeLookAt = guinfo.CurrentLookAt = new Vector3(0, 0, 0);

                    m_agentInfoService.SetHomePosition(guinfo.UserID, guinfo.HomeRegionID, guinfo.HomePosition,
                                                       guinfo.HomeLookAt);

                    MainConsole.Instance.Info("[LLLoginService]: User did not have a home, set to " +
                                              (guinfo.HomeRegionID == UUID.Zero ? "(no region found)" : guinfo.HomeRegionID.ToString()));
                }

                //
                // Find the destination region/grid
                //
                string where = string.Empty;
                Vector3 position = Vector3.Zero;
                Vector3 lookAt = Vector3.Zero;
                TeleportFlags tpFlags = TeleportFlags.ViaLogin;
                GridRegion destination = FindDestination(account, guinfo, session, startLocation, home, out tpFlags,
                                                         out where, out position, out lookAt);
                if (destination == null)
                {
                    MainConsole.Instance.InfoFormat(
                        "[LLOGIN SERVICE]: Login failed for user {0}, reason: destination not found", account.Name);
                    return LLFailedLoginResponse.DeadRegionProblem;
                }

                #region Appearance

                //
                // Get the avatar
                //
                if (m_AvatarService != null)
                {
                    bool loadedArchive;
                    avappearance = m_AvatarService.GetAndEnsureAppearance(account.PrincipalID, m_DefaultUserAvatarArchive, out loadedArchive);
                    if (loadedArchive)
                        //Must reload this, as we created a new folder
                        inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
                }
                else
                    avappearance = new AvatarAppearance(account.PrincipalID);

                if ((m_forceUserToWearFolderName != "") && (m_forceUserToWearFolderOwnerUUID.Length == 36))
                {
                    UUID userThatOwnersFolder;
                    if (UUID.TryParse(m_forceUserToWearFolderOwnerUUID, out userThatOwnersFolder))
                    {
                        avappearance = WearFolder(avappearance, account.PrincipalID, userThatOwnersFolder);
                    }
                }

                //Makes sure that all links are properly placed in the current outfit folder for v2 viewers
                FixCurrentOutFitFolder(account.PrincipalID, ref avappearance);

                #endregion

                List<UUID> friendsToInform = new List<UUID>();
                if (m_FriendsService != null)
                    friendsToInform = m_FriendsService.GetFriendOnlineStatuses(account.PrincipalID, true);

                //
                // Instantiate/get the simulation interface and launch an agent at the destination
                //
                string reason = "", seedCap = "";
                AgentCircuitData aCircuit = LaunchAgentAtGrid(destination, tpFlags, account, session,
                                                              secureSession, position, where,
                                                              clientIP, friendsToInform, out where, out reason, out seedCap,
                                                              out destination);

                if (aCircuit == null)
                {
                    MainConsole.Instance.InfoFormat("[LLOGIN SERVICE]: Login failed for user {1}, reason: {0}", reason,
                                                    account.Name);
                    return new LLFailedLoginResponse(LoginResponseEnum.InternalError, reason, false);
                }

                // Get Friends list
                List<FriendInfo> friendsList = new List<FriendInfo>();
                if (m_FriendsService != null)
                    friendsList = m_FriendsService.GetFriends(account.PrincipalID);

                //Set them as logged in now, they are ready, and fire the logged in event now, as we're all done
                m_agentInfoService.SetLastPosition(account.PrincipalID.ToString(), destination.RegionID, position,
                                                   lookAt, destination.ServerURI);
                m_agentInfoService.SetLoggedIn(account.PrincipalID.ToString(), true, destination.RegionID,
                                               destination.ServerURI);
                m_agentInfoService.FireUserStatusChangeEvent(account.PrincipalID.ToString(), true, destination.RegionID);

                //
                // Finally, fill out the response and return it
                //
                string MaturityRating = "A";
                string MaxMaturity = "A";
                if (agent != null)
                {
                    MaturityRating = agent.MaturityRating == 0
                                         ? "P"
                                         : agent.MaturityRating == 1 ? "M" : "A";
                    MaxMaturity = agent.MaxMaturity == 0
                                      ? "P"
                                      : agent.MaxMaturity == 1 ? "M" : "A";
                }

                ArrayList eventNotifications = new ArrayList();
                BuildEventNotifications(account.PrincipalID, ref eventNotifications);

                if (m_FriendsService != null)
                    m_FriendsService.SendFriendOnlineStatuses(account.PrincipalID, true);

                response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel,
                                               friendsList.ToArray(), m_InventoryService, m_LibraryService,
                                               where, startLocation, position, lookAt, gestures, home, clientIP,
                                               MaxMaturity, MaturityRating,
                                               eventCategories, eventNotifications, classifiedCategories, seedCap,
                                               m_config, DisplayName, avappearance.Serial.ToString(), m_registry.RequestModuleInterface<IGridInfo>());

                MainConsole.Instance.InfoFormat(
                    "[LLOGIN SERVICE]: All clear. Sending login response to client to login to region " +
                    destination.RegionName + ", tried to login to " + startLocation + " at " + position + ".");

                return response;
            }
            catch (Exception e)
            {
                MainConsole.Instance.WarnFormat("[LLOGIN SERVICE]: Exception processing login for {0} : {1}", Name, e);
                if (account != null)
                {
                    //Revert their logged in status if we got that far
                    m_agentInfoService.SetLoggedIn(account.PrincipalID.ToString(), false, UUID.Zero, "");
                }
                return LLFailedLoginResponse.InternalError;
            }
        }
        public bool Store (UUID PrincipalID, AvatarAppearance data)
        {
            lock (m_lock) {
                QueryFilter filter = new QueryFilter ();
                filter.andFilters ["PrincipalID"] = PrincipalID;
                Dictionary<string, object> values = new Dictionary<string, object> ();
                values.Add ("PrincipalID", PrincipalID);
                values.Add ("Appearance", OSDParser.SerializeJsonString (data.ToOSD ()));
                GD.Replace (m_realm, values);
            }

            return true;
        }
        public override void FromOSD(OSDMap map)
        {
            AgentInfo = new IAgentInfo();
            AgentInfo.FromOSD((OSDMap) (map["AgentInfo"]));
            UserAccount = new UserAccount();
            UserAccount.FromOSD((OSDMap)(map["UserAccount"]));
            if (!map.ContainsKey("ActiveGroup"))
                ActiveGroup = null;
            else
            {
                ActiveGroup = new GroupMembershipData();
                ActiveGroup.FromOSD((OSDMap)(map["ActiveGroup"]));
            }
            GroupMemberships = ((OSDArray) map["GroupMemberships"]).ConvertAll<GroupMembershipData>((o) =>
                                                                                                        {
                                                                                                            GroupMembershipData
                                                                                                                group =
                                                                                                                    new GroupMembershipData
                                                                                                                        ();
                                                                                                            group
                                                                                                                .FromOSD
                                                                                                                ((OSDMap
                                                                                                                 ) o);
                                                                                                            return group;
                                                                                                        });
            OfflineMessages = ((OSDArray) map["OfflineMessages"]).ConvertAll<GridInstantMessage>((o) =>
                                                                                                     {
                                                                                                         GridInstantMessage
                                                                                                             group =
                                                                                                                 new GridInstantMessage
                                                                                                                     ();
                                                                                                         group.FromOSD(
                                                                                                             (OSDMap) o);
                                                                                                         return group;
                                                                                                     });
            MuteList = ((OSDArray) map["MuteList"]).ConvertAll<MuteList>((o) =>
                                                                             {
                                                                                 MuteList group = new MuteList();
                                                                                 group.FromOSD((OSDMap) o);
                                                                                 return group;
                                                                             });

            if (map.ContainsKey("Appearance"))
            {
                Appearance = new AvatarAppearance();
                Appearance.FromOSD((OSDMap)map["Appearance"]);
            }
            if (map.ContainsKey("FriendOnlineStatuses"))
                FriendOnlineStatuses = ((OSDArray)map["FriendOnlineStatuses"]).ConvertAll<UUID>((o) => { return o; });
            if (map.ContainsKey("Friends"))
                Friends = ((OSDArray)map["Friends"]).ConvertAll<FriendInfo>((o) =>
                {
                    FriendInfo f = new FriendInfo();
                    f.FromOSD((OSDMap)o);
                    return f;
                });
        }
        public AvatarAppearance Get (UUID PrincipalID)
        {
            QueryFilter filter = new QueryFilter ();
            filter.andFilters ["PrincipalID"] = PrincipalID;
            List<string> data;
            lock (m_lock) {
                data = GD.Query (new string [] { "Appearance" }, m_realm, filter, null, null, null);
            }

            if (data.Count == 0)
                return null;
            
            AvatarAppearance appearance = new AvatarAppearance ();
            appearance.FromOSD ((OSDMap)OSDParser.DeserializeJson (data [0]));

            return appearance;
        }
        public void GetAssetsFrom(AvatarAppearance app)
        {
            for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
            {
                for (int j = 0; j < m_wearables[i].Count; j++)
                {
                    UUID itemID = m_wearables[i][j].ItemID;
                    UUID assetID = app.Wearables[i].GetAsset(itemID);

                    if (assetID != UUID.Zero)
                        m_wearables[i].Add(itemID, assetID);
                }
            }
        }
        public AvatarAppearance(AvatarAppearance appearance, bool copyWearables)
        {
            //MainConsole.Instance.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");

            if (appearance == null)
            {
                m_serial = 1;
                m_owner = UUID.Zero;

                SetDefaultWearables();
                SetDefaultTexture();
                SetDefaultParams();
                SetHeight();

                m_attachments = new Dictionary<int, List<AvatarAttachment>>();

                return;
            }

            m_serial = appearance.Serial;
            m_owner = appearance.Owner;

            m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
            for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
                m_wearables[i] = new AvatarWearable();

            if (copyWearables && (appearance.Wearables != null))
            {
                for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
                    SetWearable(i, appearance.Wearables[i]);
            }

            m_texture = null;
            if (appearance.Texture != null)
            {
                byte[] tbytes = appearance.Texture.GetBytes();
                m_texture = new Primitive.TextureEntry(tbytes, 0, tbytes.Length);
            }

            m_visualparams = null;

            if (appearance.VisualParams != null)
                m_visualparams = (byte [])appearance.VisualParams.Clone ();
            else
                SetDefaultParams ();    // we need something to work with
            
            SetHeight ();

            // Copy the attachment, force append mode since that ensures consistency
            m_attachments = new Dictionary<int, List<AvatarAttachment>>();
            foreach (AvatarAttachment attachment in appearance.GetAttachments())
                AppendAttachment(new AvatarAttachment(attachment));
        }
        /// <summary>
        ///     Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="e"></param>
        public void AvatarIsWearing (IClientAPI client, AvatarWearingArgs e)
        {
            IScenePresence sp = m_scene.GetScenePresence (client.AgentId);
            if (sp == null) {
                MainConsole.Instance.WarnFormat ("[AvatarFactory]: AvatarIsWearing unable to find presence for {0}",
                                                client.AgentId);
                return;
            }

            MainConsole.Instance.DebugFormat ("[AvatarFactory]: AvatarIsWearing called for {0}", client.AgentId);

            // operate on a copy of the appearance so we don't have to lock anything
            IAvatarAppearanceModule appearance = sp.RequestModuleInterface<IAvatarAppearanceModule> ();
            AvatarAppearance avatAppearance = new AvatarAppearance (appearance.Appearance, false);

            #region Teen Mode Stuff

            IOpenRegionSettingsModule module = m_scene.RequestModuleInterface<IOpenRegionSettingsModule> ();

            bool NeedsRebake = false;
            if (module != null && module.EnableTeenMode) {
                foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) {
                    if (wear.Type == 10 & wear.ItemID == UUID.Zero && module.DefaultUnderpants != UUID.Zero) {
                        NeedsRebake = true;
                        wear.ItemID = module.DefaultUnderpants;
                        InventoryItemBase item = new InventoryItemBase (UUID.Random ()) {
                            InvType = (int)InventoryType.Wearable,
                            AssetType = (int)AssetType.Clothing,
                            Name = "Default Underpants",
                            Folder =
                                m_scene.InventoryService.GetFolderForType (client.AgentId, InventoryType.Wearable, FolderType.Clothing).ID,
                            Owner = client.AgentId,
                            CurrentPermissions = 0,
                            CreatorId = UUID.Zero.ToString (),
                            AssetID = module.DefaultUnderpants
                        };
                        //Locked
                        client.SendInventoryItemCreateUpdate (item, 0);
                    } else if (wear.Type == 10 & wear.ItemID == UUID.Zero) {
                        NeedsRebake = true;
                        InventoryItemBase item = new InventoryItemBase (UUID.Random ()) {
                            InvType = (int)InventoryType.Wearable,
                            AssetType = (int)AssetType.Clothing,
                            Name = "Default Underpants",
                            Folder =
                                m_scene.InventoryService.GetFolderForType (client.AgentId, InventoryType.Wearable, FolderType.Clothing).ID,
                            Owner = client.AgentId,
                            CurrentPermissions = 0
                        };
                        //Locked
                        if (m_underPantsUUID == UUID.Zero) {
                            m_underPantsUUID = UUID.Random ();
                            AssetBase asset = new AssetBase (m_underPantsUUID, "Default Underpants", AssetType.Clothing,
                                                            UUID.Zero) { Data = Utils.StringToBytes (m_defaultUnderPants) };
                            asset.ID = m_scene.AssetService.Store (asset);
                            m_underPantsUUID = asset.ID;
                        }
                        item.CreatorId = UUID.Zero.ToString ();
                        item.AssetID = m_underPantsUUID;
                        m_scene.InventoryService.AddItemAsync (item, null);
                        client.SendInventoryItemCreateUpdate (item, 0);
                        wear.ItemID = item.ID;
                    }
                    if (wear.Type == 11 && wear.ItemID == UUID.Zero && module.DefaultUndershirt != UUID.Zero) {
                        NeedsRebake = true;
                        wear.ItemID = module.DefaultUndershirt;
                        InventoryItemBase item = new InventoryItemBase (UUID.Random ()) {
                            InvType = (int)InventoryType.Wearable,
                            AssetType = (int)AssetType.Clothing,
                            Name = "Default Undershirt",
                            Folder =
                                m_scene.InventoryService.GetFolderForType (client.AgentId, InventoryType.Wearable, FolderType.Clothing).ID,
                            Owner = client.AgentId,
                            CurrentPermissions = 0,
                            CreatorId = UUID.Zero.ToString (),
                            AssetID = module.DefaultUndershirt
                        };
                        //Locked
                        client.SendInventoryItemCreateUpdate (item, 0);
                    } else if (wear.Type == 11 & wear.ItemID == UUID.Zero) {
                        NeedsRebake = true;
                        InventoryItemBase item = new InventoryItemBase (UUID.Random ()) {
                            InvType = (int)InventoryType.Wearable,
                            AssetType = (int)AssetType.Clothing,
                            Name = "Default Undershirt",
                            Folder =
                                m_scene.InventoryService.GetFolderForType (client.AgentId, InventoryType.Wearable, FolderType.Clothing).ID,
                            Owner = client.AgentId,
                            CurrentPermissions = 0
                        };
                        //Locked
                        if (m_underShirtUUID == UUID.Zero) {
                            m_underShirtUUID = UUID.Random ();
                            AssetBase asset = new AssetBase (m_underShirtUUID, "Default Undershirt", AssetType.Clothing,
                                                            UUID.Zero) { Data = Utils.StringToBytes (m_defaultUnderShirt) };
                            asset.ID = m_scene.AssetService.Store (asset);
                            m_underShirtUUID = asset.ID;
                        }
                        item.CreatorId = UUID.Zero.ToString ();
                        item.AssetID = m_underShirtUUID;
                        m_scene.InventoryService.AddItemAsync (item, null);
                        client.SendInventoryItemCreateUpdate (item, 0);
                        wear.ItemID = item.ID;
                    }
                }
            }

            #endregion

            foreach (
                AvatarWearingArgs.Wearable wear in e.NowWearing.Where (wear => wear.Type < AvatarWearable.MAX_WEARABLES)) {
                avatAppearance.Wearables [wear.Type].Add (wear.ItemID, UUID.Zero);
            }

            avatAppearance.GetAssetsFrom (appearance.Appearance);

            // This could take awhile since it needs to pull inventory
            SetAppearanceAssets (sp.UUID, e.NowWearing, appearance.Appearance, ref avatAppearance);

            // could get fancier with the locks here, but in the spirit of "last write wins"
            // this should work correctly, also, we don't need to send the appearance here
            // since the "iswearing" will trigger a new set of visual param and baked texture changes
            // when those complete, the new appearance will be sent
            appearance.Appearance = avatAppearance;

            //This only occurs if something has been forced on afterwards (teen mode stuff)
            if (NeedsRebake) {
                //Tell the client about the new things it is wearing
                sp.ControllingClient.SendWearables (appearance.Appearance.Wearables, appearance.Appearance.Serial);
                //Then forcefully tell it to rebake
                foreach (
                    Primitive.TextureEntryFace face in
                        appearance.Appearance.Texture.FaceTextures.Select (t => (t)).Where (face => face != null)) {
                    sp.ControllingClient.SendRebakeAvatarTextures (face.TextureID);
                }
            }

            QueueAppearanceSave (sp.UUID);
            //Send the wearables HERE so that the client knows what it is wearing
            //sp.ControllingClient.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial);
            //Do not save or send the appearance! The client loops back and sends a bunch of SetAppearance
            //  (handled above) and that takes care of it
        }
        public AvatarAppearance WearFolder(AvatarAppearance avappearance, UUID user, UUID folderOwnerID)
        {
            InventoryFolderBase Folder2Wear = m_InventoryService.GetFolderByOwnerAndName(folderOwnerID, m_forceUserToWearFolderName);
            if (Folder2Wear != null)
            {
                List<InventoryItemBase> itemsInFolder = m_InventoryService.GetFolderItems(UUID.Zero, Folder2Wear.ID);

                InventoryFolderBase appearanceFolder = m_InventoryService.GetFolderForType(user, InventoryType.Wearable, FolderType.Clothing);
                InventoryFolderBase folderForAppearance = new InventoryFolderBase(UUID.Random(), "GridWear", user, -1,
                                                                                  appearanceFolder.ID, 1);
                List<InventoryFolderBase> userFolders = m_InventoryService.GetFolderFolders(user, appearanceFolder.ID);
                bool alreadyThere = false;
                List<UUID> items2RemoveFromAppearence = new List<UUID>();
                List<UUID> toDelete = new List<UUID>();

                foreach (InventoryFolderBase folder in userFolders)
                {
                    if (folder.Name == folderForAppearance.Name)
                    {
                        List<InventoryItemBase> itemsInCurrentFolder = m_InventoryService.GetFolderItems(UUID.Zero, folder.ID);
                        foreach (InventoryItemBase itemBase in itemsInCurrentFolder)
                        {
                            items2RemoveFromAppearence.Add(itemBase.AssetID);
                            items2RemoveFromAppearence.Add(itemBase.ID);
                            toDelete.Add(itemBase.ID);
                        }
                        folderForAppearance = folder;
                        alreadyThere = true;
                        m_InventoryService.DeleteItems(user, toDelete);
                        break;
                    }
                }

                if (!alreadyThere)
                    m_InventoryService.AddFolder(folderForAppearance);
                else
                {
                    // we have to remove all the old items if they are currently wearing them
                    for (int i = 0; i < avappearance.Wearables.Length; i++)
                    {
                        AvatarWearable wearable = avappearance.Wearables[i];
                        for (int ii = 0; ii < wearable.Count; ii++)
                        {
                            if (items2RemoveFromAppearence.Contains(wearable[ii].ItemID))
                            {
                                avappearance.Wearables[i] = AvatarWearable.DefaultWearables[i];
                                break;
                            }
                        }
                    }

                    List<AvatarAttachment> attachments = avappearance.GetAttachments();
                    foreach (AvatarAttachment attachment in attachments)
                    {
                        if ((items2RemoveFromAppearence.Contains(attachment.AssetID)) ||
                            (items2RemoveFromAppearence.Contains(attachment.ItemID)))
                        {
                            avappearance.DetachAttachment(attachment.ItemID);
                        }
                    }
                }

                // ok, now we have a empty folder, lets add the items
                foreach (InventoryItemBase itemBase in itemsInFolder)
                {
                    InventoryItemBase newcopy = m_InventoryService.InnerGiveInventoryItem(user, folderOwnerID, itemBase,
                                                                                          folderForAppearance.ID,
                                                                                          true, true);

                    if (newcopy.InvType == (int) InventoryType.Object)
                    {
                        byte[] attobj = m_AssetService.GetData(newcopy.AssetID.ToString());

                        if (attobj != null)
                        {
                            string xmlData = Utils.BytesToString(attobj);
                            XmlDocument doc = new XmlDocument();
                            try
                            {
                                doc.LoadXml(xmlData);
                            }
                            catch
                            {
                                continue;
                            }

                            if (doc.FirstChild.OuterXml.StartsWith("<groups>") ||
                                (doc.FirstChild.NextSibling != null &&
                                 doc.FirstChild.NextSibling.OuterXml.StartsWith("<groups>")))
                                continue;

                            string xml;
                            if ((doc.FirstChild.NodeType == XmlNodeType.XmlDeclaration) &&
                                (doc.FirstChild.NextSibling != null))
                                xml = doc.FirstChild.NextSibling.OuterXml;
                            else
                                xml = doc.FirstChild.OuterXml;
                            doc.LoadXml(xml);

                            if (doc.DocumentElement == null) continue;

                            XmlNodeList xmlNodeList = doc.DocumentElement.SelectNodes("//State");
                            int attchspot;
                            if ((xmlNodeList != null) && (int.TryParse(xmlNodeList[0].InnerText, out attchspot)))
                            {
                                AvatarAttachment a = new AvatarAttachment(attchspot, newcopy.ID, newcopy.AssetID);
                                Dictionary<int, List<AvatarAttachment>> ac = avappearance.Attachments;

                                if (!ac.ContainsKey(attchspot))
                                    ac[attchspot] = new List<AvatarAttachment>();

                                ac[attchspot].Add(a);
                                avappearance.Attachments = ac;
                            }
                        }
                    }
                    m_InventoryService.AddItem(newcopy);
                }
            }
            return avappearance;
        }
        void SetAppearanceAssets (UUID userID, List<AvatarWearingArgs.Wearable> nowWearing,
                                         AvatarAppearance oldAppearance, ref AvatarAppearance appearance)
        {
            IInventoryService invService = m_scene.InventoryService;

            for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) {
                for (int j = 0; j < appearance.Wearables [j].Count; j++) {
                    if (appearance.Wearables [i] [j].ItemID == UUID.Zero)
                        continue;

                    // ItemIDs will be updated with new assetIDs if the avatar has just updated their clothing,
                    //    so we can't assume this...
                    //if (nowWearing[i].ItemID == oldAppearance.Wearables[i][j].ItemID)
                    //    continue; //Don't relookup items that are the same and have already been found earlier

                    UUID assetID = invService.GetItemAssetID (userID, appearance.Wearables [i] [j].ItemID);

                    if (assetID != UUID.Zero)
                        appearance.Wearables [i].Add (nowWearing [i].ItemID, assetID);
                    else {
                        MainConsole.Instance.ErrorFormat (
                            "[AvatarFactory]: Can't find inventory item {0} for {1}, setting to default",
                            appearance.Wearables [i] [j].ItemID, (WearableType)i);

                        appearance.Wearables [i].RemoveItem (appearance.Wearables [i] [j].ItemID);
                        appearance.Wearables [i].Add (AvatarWearable.DefaultWearables [i] [j].ItemID,
                                                    AvatarWearable.DefaultWearables [i] [j].AssetID);
                    }
                }
            }
        }
        public override void FromOSD(OSDMap args)
        {
            if (args.ContainsKey("region_id"))
                UUID.TryParse(args["region_id"].AsString(), out RegionID);

            if (args["circuit_code"] != null)
                UInt32.TryParse(args["circuit_code"].AsString(), out CircuitCode);

            if (args["agent_uuid"] != null)
                AgentID = args["agent_uuid"].AsUUID();

            if (args["session_uuid"] != null)
                SessionID = args["session_uuid"].AsUUID();

            if (args["position"] != null)
                Vector3.TryParse(args["position"].AsString(), out Position);

            if (args["velocity"] != null)
                Vector3.TryParse(args["velocity"].AsString(), out Velocity);

            if (args["center"] != null)
                Vector3.TryParse(args["center"].AsString(), out Center);

            if (args["size"] != null)
                Vector3.TryParse(args["size"].AsString(), out Size);

            if (args["at_axis"] != null)
                Vector3.TryParse(args["at_axis"].AsString(), out AtAxis);

            if (args["left_axis"] != null)
                Vector3.TryParse(args["left_axis"].AsString(), out AtAxis);

            if (args["up_axis"] != null)
                Vector3.TryParse(args["up_axis"].AsString(), out AtAxis);

            if (args["far"] != null)
                Far = (float) (args["far"].AsReal());

            if (args["aspect"] != null)
                Aspect = (float) args["aspect"].AsReal();

            if (args["throttles"] != null)
                Throttles = args["throttles"].AsBinary();

            if (args["locomotion_state"] != null)
                UInt32.TryParse(args["locomotion_state"].AsString(), out LocomotionState);

            if (args["head_rotation"] != null)
                Quaternion.TryParse(args["head_rotation"].AsString(), out HeadRotation);

            if (args["body_rotation"] != null)
                Quaternion.TryParse(args["body_rotation"].AsString(), out BodyRotation);

            if (args["control_flags"] != null)
                UInt32.TryParse(args["control_flags"].AsString(), out ControlFlags);

            if (args["energy_level"] != null)
                EnergyLevel = (float) (args["energy_level"].AsReal());

            //This IS checked later
            if (args["god_level"] != null)
                Byte.TryParse(args["god_level"].AsString(), out GodLevel);

            if (args["speed"] != null)
                float.TryParse(args["speed"].AsString(), out Speed);
            else
                Speed = 1;

            if (args["draw_distance"] != null)
                float.TryParse(args["draw_distance"].AsString(), out DrawDistance);
            else
                DrawDistance = 0;

            //Reset this to fix movement... since regions are being bad about this
            if (Speed == 0)
                Speed = 1;

            if (args["always_run"] != null)
                AlwaysRun = args["always_run"].AsBoolean();

            SentInitialWearables = args["sent_initial_wearables"] != null && args["sent_initial_wearables"].AsBoolean();

            if (args["prey_agent"] != null)
                PreyAgent = args["prey_agent"].AsUUID();

            if (args["agent_access"] != null)
                Byte.TryParse(args["agent_access"].AsString(), out AgentAccess);

            if (args["active_group_id"] != null)
                ActiveGroupID = args["active_group_id"].AsUUID();

            if (args["IsCrossing"] != null)
                IsCrossing = args["IsCrossing"].AsBoolean();

            if ((args["animations"] != null) && (args["animations"]).Type == OSDType.Array)
            {
                OSDArray anims = (OSDArray) (args["animations"]);
                Anims = new Animation[anims.Count];
                int i = 0;

                foreach (OSD o in anims.Where(o => o.Type == OSDType.Map))
                {
                    Anims[i++] = new Animation((OSDMap) o);
                }
            }

            Appearance = new AvatarAppearance(AgentID);

            try
            {
                if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
                    Appearance = new AvatarAppearance(AgentID, (OSDMap) args["packed_appearance"]);
                    // DEBUG ON
                else
                    MainConsole.Instance.Warn("[CHILDAGENTDATAUPDATE] No packed appearance");
                // DEBUG OFF
            }
            catch
            {
            }

            if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
            {
                OSDArray controls = (OSDArray) (args["controllers"]);
                Controllers = new ControllerData[controls.Count];
                int i = 0;

                foreach (OSD o in controls.Where(o => o.Type == OSDType.Map))
                {
                    Controllers[i++] = new ControllerData((OSDMap) o);
                }
            }

            if (args["SittingObjects"] != null && args["SittingObjects"].Type == OSDType.Map)
                SittingObjects = new SittingObjectData((OSDMap) args["SittingObjects"]);
        }
        protected LSL_Key SaveAppearanceToNotecard(IScenePresence sp, string notecard)
        {
            IAvatarAppearanceModule aa = sp.RequestModuleInterface<IAvatarAppearanceModule> ();
            if (aa != null)
            {
                var appearance = new AvatarAppearance (aa.Appearance);
                OSDMap appearancePacked = appearance.Pack ();
 
                TaskInventoryItem item
                = SaveNotecard (notecard, "Avatar Appearance", OSDParser.SerializeLLSDXmlString(appearancePacked), true);
 
                return new LSL_Key (item.AssetID.ToString ());
            }
        
            return new LSL_Key(UUID.Zero.ToString());
        }
        public UUID CreateAvatar(string firstName, string lastName, IScene scene, AvatarAppearance avatarApp,
            UUID creatorID, Vector3 startPos)
        {
            //Add the circuit data so they can login
            AgentCircuitData m_aCircuitData = new AgentCircuitData
            {
                IsChildAgent = false,
                CircuitCode = (uint) Util.RandomClass.Next()
            };

            //Create the new bot data
            BotClientAPI m_character = new BotClientAPI(scene, m_aCircuitData);
            m_character.Name = firstName + " " + lastName;
            m_aCircuitData.AgentID = m_character.AgentId;

            //Set up appearance
            var origOwner = avatarApp.Owner;
            avatarApp.Owner = m_character.AgentId;
            List<AvatarAttachment> attachments = avatarApp.GetAttachments();

            avatarApp.ClearAttachments();
            // get original attachments
            foreach (AvatarAttachment t in attachments)
            {
                InventoryItemBase item = scene.InventoryService.GetItem(origOwner, t.ItemID);
                if (item != null)
                {
                    item.ID = UUID.Random();
                    item.Owner = m_character.AgentId;
                    item.Folder = UUID.Zero;
                    scene.InventoryService.AddCacheItemAsync(item);
                    //Now fix the ItemID
                    avatarApp.SetAttachment(t.AttachPoint, item.ID, t.AssetID);
                }
            }

            scene.AuthenticateHandler.AgentCircuits.Add(m_character.CircuitCode, m_aCircuitData);
            //This adds them to the scene and sets them inworld
            AddAndWaitUntilAgentIsAdded(scene, m_character);

            IScenePresence SP = scene.GetScenePresence(m_character.AgentId);
            if (SP == null)
                return UUID.Zero; //Failed!

            IAvatarAppearanceModule appearance = SP.RequestModuleInterface<IAvatarAppearanceModule>();
            appearance.Appearance = avatarApp;
            appearance.InitialHasWearablesBeenSent = true;
            Bot bot = new Bot();
            bot.Initialize(SP, creatorID);
            SP.MakeRootAgent(startPos, false, true);
            //Move them
            SP.Teleport(startPos);

            foreach (var presence in scene.GetScenePresences())
                presence.SceneViewer.QueuePresenceForUpdate(SP, PrimUpdateFlags.ForcedFullUpdate);
            IAttachmentsModule attModule = SP.Scene.RequestModuleInterface<IAttachmentsModule>();
            if (attModule != null)
                foreach (AvatarAttachment att in attachments)
                    attModule.RezSingleAttachmentFromInventory(SP.ControllingClient, att.ItemID, att.AssetID, 0, true);

            //Save them in the bots list
            m_bots.Add(m_character.AgentId, bot);
            AddTagToBot(m_character.AgentId, "AllBots", bot.AvatarCreatorID);

            MainConsole.Instance.InfoFormat("[BotManager]: Added bot {0} to region {1}",
                m_character.Name, scene.RegionInfo.RegionName);

            //Return their UUID
            return m_character.AgentId;
        }
        public void osNpcLoadAppearance(LSL_Key npc, string notecard)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance", m_host, "OSSL", m_itemID))
                return;

            IBotManager manager = World.RequestModuleInterface<IBotManager>();
            if (manager != null)
            {
                UUID npcId;
                if (!UUID.TryParse(npc.m_string, out npcId))
                    return;

                if (!manager.CheckPermission(npcId, m_host.OwnerID))
                    return;

                string appearanceSerialized = LoadNotecard(notecard);

                if (appearanceSerialized == null)
                    OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard));

                OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
                AvatarAppearance appearance = new AvatarAppearance();
                appearance.Unpack(appearanceOsd);

                manager.SetAvatarAppearance(npcId, appearance, m_host.ParentEntity.Scene);
            }
        }
 AvatarAppearance ConvertXMLToAvatarAppearance (OSDMap map)
 {
     AvatarAppearance appearance = new AvatarAppearance ();
     appearance.Unpack (map);
     return appearance;
 }
        AvatarAppearance CopyWearablesAndAttachments (UUID destination, UUID source,
                                                             AvatarAppearance avatarAppearance,
                                                             InventoryFolderBase destinationFolder, UUID agentid,
                                                             OSDMap itemsMap,
                                                             out List<InventoryItemBase> items)
        {
            items = new List<InventoryItemBase> ();

            if (destinationFolder == null) {
                MainConsole.Instance.Error ("[Avatar Archiver]: Cannot locate folder(s) for copying wearables!");
                return avatarAppearance;
            }

            List<InventoryItemBase> litems = new List<InventoryItemBase> ();
            foreach (KeyValuePair<string, OSD> kvp in itemsMap) {
                InventoryItemBase item = new InventoryItemBase ();
                item.FromOSD ((OSDMap)kvp.Value);
                MainConsole.Instance.Info ("[Avatar Archiver]: Loading item " + item.ID);
                litems.Add (item);
            }

            // Wearables
            AvatarWearable [] wearables = avatarAppearance.Wearables;
            MainConsole.Instance.InfoFormat ("[Avatar Archiver] Adding {0} wearables", wearables.Length);

            for (int i = 0; i < wearables.Length; i++) {
                AvatarWearable wearable = wearables [i];
                for (int ii = 0; ii < wearable.Count; ii++) {
                    if (wearable [ii].ItemID != UUID.Zero) {
                        // Get inventory item and copy it
                        InventoryItemBase item = inventoryService.GetItem (UUID.Zero, wearable [ii].ItemID);

                        if (item == null) {
                            //Attempt to get from the map if it doesn't already exist on the grid
                            item = litems.First ((itm) => itm.ID == wearable [ii].ItemID);
                        }
                        if (item != null) {
                            InventoryItemBase destinationItem = inventoryService.InnerGiveInventoryItem (destination,
                                                                                                        destination,
                                                                                                        item,
                                                                                                        destinationFolder
                                                                                                            .ID,
                                                                                                        false, false);
                            items.Add (destinationItem);
                            MainConsole.Instance.DebugFormat ("[Avatar Archiver]: Added item {0} to folder {1}",
                                                             destinationItem.ID, destinationFolder.ID);

                            // Wear item
                            AvatarWearable newWearable = new AvatarWearable ();
                            newWearable.Wear (destinationItem.ID, destinationItem.AssetID);
                            avatarAppearance.SetWearable (i, newWearable);
                        } else {
                            MainConsole.Instance.WarnFormat ("[Avatar Archiver]: Unable to transfer {0} to folder {1}",
                                                            wearable [ii].ItemID, destinationFolder.ID);
                        }
                    }
                }
            }

            // Attachments
            List<AvatarAttachment> attachments = avatarAppearance.GetAttachments ();
            MainConsole.Instance.InfoFormat ("[Avatar Archiver] Adding {0} attachments", attachments.Count);

            foreach (AvatarAttachment attachment in attachments) {
                int attachpoint = attachment.AttachPoint;
                UUID itemID = attachment.ItemID;

                if (itemID != UUID.Zero) {

                    // Get inventory item and copy it
                    InventoryItemBase item = inventoryService.GetItem (UUID.Zero, itemID);

                    if (item == null) {
                        //Attempt to get from the map if it doesn't already exist on the grid
                        item = litems.First ((itm) => itm.ID == itemID);
                    }

                    if (item != null) {
                        InventoryItemBase destinationItem = inventoryService.InnerGiveInventoryItem (destination,
                                                                                                    destination, item,
                                                                                                    destinationFolder.ID,
                                                                                                    false, false);
                        items.Add (destinationItem);
                        MainConsole.Instance.DebugFormat ("[Avatar Archiver]: Added item {0} to folder {1}", destinationItem.ID,
                                                         destinationFolder.ID);

                        // Attach item
                        avatarAppearance.SetAttachment (attachpoint, destinationItem.ID, destinationItem.AssetID);
                        MainConsole.Instance.DebugFormat ("[Avatar Archiver]: Attached {0}", destinationItem.ID);
                    } else {
                        MainConsole.Instance.WarnFormat ("[Avatar Archiver]: Error transferring {0} to folder {1}", itemID,
                                                        destinationFolder.ID);
                    }
                }
            }
            return avatarAppearance;
        }
        public bool SetAvatarAppearance(UUID botID, AvatarAppearance avatarApp, IScene scene)
        {
            Bot bot;
            //Find the bot
            if (!m_bots.TryGetValue (botID, out bot))
                return false;

            var origOwner = avatarApp.Owner;
            avatarApp.Owner = botID;

            List<AvatarAttachment> attachments = avatarApp.GetAttachments();

            avatarApp.ClearAttachments();
            // get original attachments
            foreach (AvatarAttachment t in attachments)
            {
                InventoryItemBase item = scene.InventoryService.GetItem(origOwner, t.ItemID);
                if (item != null)
                {
                    item.ID = UUID.Random();
                    item.Owner = botID;
                    item.Folder = UUID.Zero;
                    scene.InventoryService.AddCacheItemAsync(item);
                    //Now fix the ItemID
                    avatarApp.SetAttachment(t.AttachPoint, item.ID, t.AssetID);
                }
            }

            IScenePresence SP = scene.GetScenePresence(botID);
            if (SP == null)
                return false;   // Failed! bot not found??

            IAvatarAppearanceModule appearance = SP.RequestModuleInterface<IAvatarAppearanceModule>();
            appearance.Appearance = avatarApp;
            appearance.InitialHasWearablesBeenSent = true;

            return true;
        }