public bool SetAppearance(UUID userID, AvatarAppearance appearance)
 {
     bool success = m_localService.SetAppearance(userID, appearance);
     if (!success)
         success = m_remoteService.SetAppearance(userID, appearance);
     return success;
 }
 public bool SetAppearance(UUID principalID, AvatarAppearance appearance)
 {
     bool success = m_localService.SetAppearance(principalID, appearance);
     if (!success)
         success = (bool)DoRemoteForced(principalID, appearance);
     return success;
 }
        /// <summary>
        ///   Unpack agent circuit data map into an AgentCiruitData object
        /// </summary>
        /// <param name = "args"></param>
        public virtual void UnpackAgentCircuitData(OSDMap args)
        {
            if (args["agent_id"] != null)
                AgentID = args["agent_id"].AsUUID();
            if (args["caps_path"] != null)
                CapsPath = args["caps_path"].AsString();
            if (args["reallyischild"] != null)
                reallyischild = args["reallyischild"].AsBoolean();
            if (args["child"] != null)
                child = args["child"].AsBoolean();
            if (args["circuit_code"] != null)
                UInt32.TryParse(args["circuit_code"].AsString(), out circuitcode);
            if (args["secure_session_id"] != null)
                SecureSessionID = args["secure_session_id"].AsUUID();
            if (args["session_id"] != null)
                SessionID = args["session_id"].AsUUID();
            if (args["service_session_id"] != null)
                ServiceSessionID = args["service_session_id"].AsString();
            if (args["client_ip"] != null)
                IPAddress = args["client_ip"].AsString();
            if (args["first_name"] != null)
                firstname = args["first_name"].AsString();
            if (args["last_name"] != null)
                lastname = args["last_name"].AsString();

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

            if (args["teleport_flags"] != null)
                teleportFlags = args["teleport_flags"].AsUInteger();
            if (args["draw_distance"] != null)
                DrawDistance = args["draw_distance"];

            // DEBUG ON
            //MainConsole.Instance.WarnFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}", AgentID, child, startpos.ToString());
            // DEBUG OFF

            try
            {
                // Unpack various appearance elements
                Appearance = new AvatarAppearance(AgentID);

                // Eventually this code should be deprecated, use full appearance
                // packing in packed_appearance
                if (args["appearance_serial"] != null)
                    Appearance.Serial = args["appearance_serial"].AsInteger();

                if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
                {
                    Appearance.Unpack((OSDMap)args["packed_appearance"]);
                    // DEBUG ON
                    //MainConsole.Instance.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance");
                    // DEBUG OFF
                }
                // DEBUG ON
                else
                    MainConsole.Instance.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance, dne ? " +
                               !args.ContainsKey("packed_appearance"));
                // DEBUG OFF
            }
            catch (Exception e)
            {
                MainConsole.Instance.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}", e);
            }

            if (args.ContainsKey("otherInfo"))
                OtherInformation = (OSDMap)OSDParser.DeserializeLLSDXml(args["otherInfo"].AsString());

            ServiceURLs = new Dictionary<string, object>();
            // Try parse the new way, OSDMap
            if (args.ContainsKey("serviceurls") && args["serviceurls"] != null &&
                (args["serviceurls"]).Type == OSDType.Map)
            {
                OSDMap urls = (OSDMap)(args["serviceurls"]);
                foreach (KeyValuePair<String, OSD> kvp in urls)
                {
                    ServiceURLs[kvp.Key] = kvp.Value.AsString();
                    //System.Console.WriteLine("XXX " + kvp.Key + "=" + ServiceURLs[kvp.Key]);
                }
            }
        }
        private 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;

                    // Ignore ruth's assets
                    if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][j].ItemID)
                    {
                        //MainConsole.Instance.ErrorFormat(
                        //    "[AvatarFactory]: Found an asset for the default avatar, itemID {0}, wearable {1}, asset {2}" +
                        //    ", setting to default asset {3}.",
                        //    appearance.Wearables[i][j].ItemID, (WearableType)i, appearance.Wearables[i][j].AssetID,
                        //    AvatarWearable.DefaultWearables[i][j].AssetID);
                        appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID,
                                                    appearance.Wearables[i][j].AssetID);
                        continue;
                    }

                    if (nowWearing[i].ItemID == oldAppearance.Wearables[i][j].ItemID)
                        continue;//Don't relookup items that are the same and have already been found earlier

                    InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
                    baseItem = invService.GetItem(baseItem);

                    if (baseItem != null)
                    {
                        if (baseItem.AssetType == (int) AssetType.Link)
                        {
                            baseItem = new InventoryItemBase(baseItem.AssetID, userID);
                            baseItem = invService.GetItem(baseItem);
                        }
                        appearance.Wearables[i].Add(baseItem.ID, baseItem.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 AvatarAppearance ToAvatarAppearance(UUID owner)
        {
            AvatarAppearance appearance = new AvatarAppearance(owner);

            if (Data.Count == 0)
                return appearance;

            appearance.ClearWearables();
            try
            {
                if (Data.ContainsKey("Serial"))
                    appearance.Serial = Int32.Parse(Data["Serial"]);

                if (Data.ContainsKey("AvatarHeight"))
                    appearance.AvatarHeight = float.Parse(Data["AvatarHeight"]);

                // Legacy Wearables
                if (Data.ContainsKey("BodyItem"))
                    appearance.Wearables[AvatarWearable.BODY].Wear(
                        UUID.Parse(Data["BodyItem"]),
                        UUID.Parse(Data["BodyAsset"]));

                if (Data.ContainsKey("SkinItem"))
                    appearance.Wearables[AvatarWearable.SKIN].Wear(
                        UUID.Parse(Data["SkinItem"]),
                        UUID.Parse(Data["SkinAsset"]));

                if (Data.ContainsKey("HairItem"))
                    appearance.Wearables[AvatarWearable.HAIR].Wear(
                        UUID.Parse(Data["HairItem"]),
                        UUID.Parse(Data["HairAsset"]));

                if (Data.ContainsKey("EyesItem"))
                    appearance.Wearables[AvatarWearable.EYES].Wear(
                        UUID.Parse(Data["EyesItem"]),
                        UUID.Parse(Data["EyesAsset"]));

                if (Data.ContainsKey("ShirtItem"))
                    appearance.Wearables[AvatarWearable.SHIRT].Wear(
                        UUID.Parse(Data["ShirtItem"]),
                        UUID.Parse(Data["ShirtAsset"]));

                if (Data.ContainsKey("PantsItem"))
                    appearance.Wearables[AvatarWearable.PANTS].Wear(
                        UUID.Parse(Data["PantsItem"]),
                        UUID.Parse(Data["PantsAsset"]));

                if (Data.ContainsKey("ShoesItem"))
                    appearance.Wearables[AvatarWearable.SHOES].Wear(
                        UUID.Parse(Data["ShoesItem"]),
                        UUID.Parse(Data["ShoesAsset"]));

                if (Data.ContainsKey("SocksItem"))
                    appearance.Wearables[AvatarWearable.SOCKS].Wear(
                        UUID.Parse(Data["SocksItem"]),
                        UUID.Parse(Data["SocksAsset"]));

                if (Data.ContainsKey("JacketItem"))
                    appearance.Wearables[AvatarWearable.JACKET].Wear(
                        UUID.Parse(Data["JacketItem"]),
                        UUID.Parse(Data["JacketAsset"]));

                if (Data.ContainsKey("GlovesItem"))
                    appearance.Wearables[AvatarWearable.GLOVES].Wear(
                        UUID.Parse(Data["GlovesItem"]),
                        UUID.Parse(Data["GlovesAsset"]));

                if (Data.ContainsKey("UnderShirtItem"))
                    appearance.Wearables[AvatarWearable.UNDERSHIRT].Wear(
                        UUID.Parse(Data["UnderShirtItem"]),
                        UUID.Parse(Data["UnderShirtAsset"]));

                if (Data.ContainsKey("UnderPantsItem"))
                    appearance.Wearables[AvatarWearable.UNDERPANTS].Wear(
                        UUID.Parse(Data["UnderPantsItem"]),
                        UUID.Parse(Data["UnderPantsAsset"]));

                if (Data.ContainsKey("SkirtItem"))
                    appearance.Wearables[AvatarWearable.SKIRT].Wear(
                        UUID.Parse(Data["SkirtItem"]),
                        UUID.Parse(Data["SkirtAsset"]));

                if (Data.ContainsKey("VisualParams"))
                {
                    string[] vps = Data["VisualParams"].Split(new[] {','});
                    byte[] binary = new byte[AvatarAppearance.VISUALPARAM_COUNT];

                    for (int i = 0; i < vps.Length && i < binary.Length; i++)
                        binary[i] = (byte) Convert.ToInt32(vps[i]);

                    appearance.VisualParams = binary;
                }

                if (Data.ContainsKey("Textures"))
                {
                    string t = Data["Textures"];
                    OSD tex = OSDParser.DeserializeJson(t);
                    appearance.Texture = Primitive.TextureEntry.FromOSD(tex);
                }

                // New style wearables
                foreach (KeyValuePair<string, string> _kvp in Data)
                {
                    if (_kvp.Key.StartsWith("Wearable "))
                    {
                        string wearIndex = _kvp.Key.Substring(9);
                        string[] wearIndices = wearIndex.Split(new[] {':'});
                        if (wearIndices.Length == 2 && wearIndices[1].Length == 1)
                        {
                            int index = Convert.ToInt32(wearIndices[0]);

                            string[] ids = _kvp.Value.Split(new[] { ':' });
                            UUID itemID = new UUID(ids[0]);
                            UUID assetID = new UUID(ids[1]);
                            appearance.Wearables[index].Add(itemID, assetID);
                        }
                        else
                        {
                            //For when we get stuff like 0020_0_x003A_0
                            var index2 = wearIndices[1].Split('_');
                            int index = Convert.ToInt32(index2[1]);

                            string[] ids = _kvp.Value.Split(new[] { ':' });
                            UUID itemID = new UUID(ids[0]);
                            UUID assetID = new UUID(ids[1]);
                            appearance.Wearables[index].Add(itemID, assetID);
                        }
                    }
                }

                // Attachments
                Dictionary<string, string> attchs = new Dictionary<string, string>();
                Dictionary<string, string> attchsAssets = new Dictionary<string, string>();
            #if (!ISWIN)
                foreach (KeyValuePair<string, string> _kvp in Data)
                {
                    if (_kvp.Key.StartsWith("_ap_")) attchs[_kvp.Key] = _kvp.Value;
                    if (_kvp.Key.StartsWith("_apa_")) attchsAssets[_kvp.Key] = _kvp.Value;
                }
            #else
                foreach (KeyValuePair<string, string> _kvp in Data.Where(_kvp => _kvp.Key.StartsWith("_ap_")))
                    attchs[_kvp.Key] = _kvp.Value;
            #endif

                foreach (KeyValuePair<string, string> _kvp in attchs)
                {
                    string pointStr = _kvp.Key.Substring(4);
                    int point = 0;
                    if (!Int32.TryParse(pointStr, out point))
                        continue;

                    UUID uuid = UUID.Zero;
                    UUID.TryParse(_kvp.Value, out uuid);
                    UUID assetuuid = UUID.Zero;
                    if(attchsAssets.ContainsKey(_kvp.Key))
                        UUID.TryParse(attchsAssets[_kvp.Key], out uuid);

                    appearance.SetAttachment(point, uuid, assetuuid);
                }

                if (appearance.Wearables[AvatarWearable.BODY].Count == 0)
                    appearance.Wearables[AvatarWearable.BODY].Wear(
                        AvatarWearable.DefaultWearables[
                            AvatarWearable.BODY][0]);

                if (appearance.Wearables[AvatarWearable.SKIN].Count == 0)
                    appearance.Wearables[AvatarWearable.SKIN].Wear(
                        AvatarWearable.DefaultWearables[
                            AvatarWearable.SKIN][0]);

                if (appearance.Wearables[AvatarWearable.HAIR].Count == 0)
                    appearance.Wearables[AvatarWearable.HAIR].Wear(
                        AvatarWearable.DefaultWearables[
                            AvatarWearable.HAIR][0]);

                if (appearance.Wearables[AvatarWearable.EYES].Count == 0)
                    appearance.Wearables[AvatarWearable.EYES].Wear(
                        AvatarWearable.DefaultWearables[
                            AvatarWearable.EYES][0]);
            }
            catch
            {
                // We really should report something here, returning null
                // will at least break the wrapper
                return null;
            }

            return appearance;
        }
Exemple #6
0
        public LoginResponse Login(string Name, string passwd, string startLocation, UUID scopeID,
            string clientVersion, string channel, string mac, string id0, IPEndPoint clientIP, Hashtable requestData, UUID secureSession)
        {
            UUID session = UUID.Random();

            MainConsole.Instance.InfoFormat("[LLOGIN SERVICE]: Login request for {0} from {1} with user agent {2} starting in {3}",
                Name, clientIP.Address, clientVersion, startLocation);
            UserAccount account = m_UserAccountService.GetUserAccount (scopeID, Name);
            try
            {
                string DisplayName = account.Name;
                IAgentInfo agent = null;

                IAgentConnector agentData = DataManager.RequestPlugin<IAgentConnector>();
                IProfileConnector profileData = DataManager.RequestPlugin<IProfileConnector>();
                if (agentData != null)
                    agent = agentData.GetAgent(account.PrincipalID);

                requestData["ip"] = clientIP.ToString();
                foreach (ILoginModule module in LoginModules)
                {
                    string message;
                    if (!module.Login(requestData, account.PrincipalID, out message))
                    {
                        LLFailedLoginResponse resp = new LLFailedLoginResponse(LoginResponseEnum.PasswordIncorrect,
                            message, false);
                        return resp;
                    }
                }
                

                //
                // Get the user's inventory
                //
                if (m_RequireInventory && m_InventoryService == null)
                {
                    MainConsole.Instance.WarnFormat("[LLOGIN SERVICE]: Login failed, reason: inventory service not set up");
                    return LLFailedLoginResponse.InventoryProblem;
                }
                List<InventoryFolderBase> inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
                if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel.Count == 0)))
                {
                    m_InventoryService.CreateUserInventory(account.PrincipalID, m_DefaultUserAvatarArchive == "");
                    inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
                    if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel.Count == 0)))
                    {
                        MainConsole.Instance.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: unable to retrieve user inventory");
                        return LLFailedLoginResponse.InventoryProblem;
                    }
                }
                if (m_InventoryService.CreateUserRootFolder (account.PrincipalID))
                    //Gotta refetch... since something went wrong
                    inventorySkel = m_InventoryService.GetInventorySkeleton (account.PrincipalID);

                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 != "")
                    {
                        AvatarAppearance appearance = m_ArchiveService.LoadAvatarArchive(archiveName, account.Name);
                        UPI.AArchiveName = "";
                        inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
                        AvatarData adata = new AvatarData(appearance);
                        m_AvatarService.SetAppearance(account.PrincipalID, appearance);
                    }
                    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);

                //Reset logged in to true if the user was crashed, but don't fire the logged in event yet
                m_agentInfoService.SetLoggedIn (account.PrincipalID.ToString (), true, false, UUID.Zero);
                //Lock it as well
                m_agentInfoService.LockLoggedInStatus (account.PrincipalID.ToString (), true);
                //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(scopeID, guinfo.HomeRegionID);
                }
                bool GridUserInfoFound = true;
                if (guinfo == null)
                {
                    GridUserInfoFound = false;
                    // something went wrong, make something up, so that we don't have to test this anywhere else
                    guinfo = new UserInfo {UserID = account.PrincipalID.ToString()};
                    guinfo.CurrentPosition = guinfo.HomePosition = new Vector3(128, 128, 30);
                }

                //
                // 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, scopeID, guinfo, session, startLocation, home, out tpFlags, out where, out position, out lookAt);
                if (destination == null)
                {
                    MainConsole.Instance.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: destination not found");
                    return LLFailedLoginResponse.DeadRegionProblem;
                }
                if (!GridUserInfoFound || guinfo.HomeRegionID == UUID.Zero) //Give them a default home and last
                {
                    if (m_GridService != null)
                    {
                        List<GridRegion> DefaultRegions = m_GridService.GetDefaultRegions(account.ScopeID);
                        GridRegion DefaultRegion = null;
                        DefaultRegion = DefaultRegions.Count == 0 ? destination : DefaultRegions[0];

                        if (m_DefaultHomeRegion != "" && guinfo.HomeRegionID == UUID.Zero)
                        {
                            GridRegion newHomeRegion = m_GridService.GetRegionByName(account.ScopeID, m_DefaultHomeRegion);
                            if (newHomeRegion == null)
                                guinfo.HomeRegionID = guinfo.CurrentRegionID = DefaultRegion.RegionID;
                            else
                                guinfo.HomeRegionID = guinfo.CurrentRegionID = newHomeRegion.RegionID;
                        }
                        else if (guinfo.HomeRegionID == UUID.Zero)
                            guinfo.HomeRegionID = guinfo.CurrentRegionID = DefaultRegion.RegionID;
                    }

                    //Z = 0 so that it fixes it on the region server and puts it on the ground
                    guinfo.CurrentPosition = guinfo.HomePosition = new Vector3(128, 128, 25);

                    guinfo.HomeLookAt = guinfo.CurrentLookAt = new Vector3(0, 0, 0);

                    m_agentInfoService.SetLastPosition(guinfo.UserID, guinfo.CurrentRegionID, guinfo.CurrentPosition, guinfo.CurrentLookAt);
                    m_agentInfoService.SetHomePosition(guinfo.UserID, guinfo.HomeRegionID, guinfo.HomePosition, guinfo.HomeLookAt);
                }

                //
                // Get the avatar
                //
                AvatarAppearance avappearance;
                if (m_AvatarService != null)
                {
                    avappearance = m_AvatarService.GetAppearance(account.PrincipalID);
                    if (avappearance == null)
                    {
                        //Create an appearance for the user if one doesn't exist
                        if (m_DefaultUserAvatarArchive != "")
                        {
                            MainConsole.Instance.Error("[LLoginService]: Cannot find an appearance for user " + account.Name +
                                ", loading the default avatar from " + m_DefaultUserAvatarArchive + ".");
                            m_ArchiveService.LoadAvatarArchive(m_DefaultUserAvatarArchive, account.Name);
                        }
                        else
                        {
                            MainConsole.Instance.Error("[LLoginService]: Cannot find an appearance for user " + account.Name + ", setting to the default avatar.");
                            AvatarAppearance appearance = new AvatarAppearance(account.PrincipalID);
                            m_AvatarService.SetAvatar(account.PrincipalID, new AvatarData(appearance));
                        }
                        avappearance = m_AvatarService.GetAppearance(account.PrincipalID);
                    }
                    else
                    {
                        //Verify that all assets exist now
                        for (int i = 0; i < avappearance.Wearables.Length; i++)
                        {
                            bool messedUp = false;
                            foreach (KeyValuePair<UUID, UUID> item in avappearance.Wearables[i].GetItems())
                            {
                                AssetBase asset = m_AssetService.Get(item.Value.ToString());
                                if (asset == null)
                                {
                                    InventoryItemBase invItem = m_InventoryService.GetItem (new InventoryItemBase (item.Value));
                                    if (invItem == null)
                                    {
                                        MainConsole.Instance.Warn("[LLOGIN SERVICE]: Missing avatar appearance asset for user " + account.Name + " for item " + item.Value + ", asset should be " + item.Key + "!");
                                        messedUp = true;
                                    }
                                }
                            }
                            if (messedUp)
                                avappearance.Wearables[i] = AvatarWearable.DefaultWearables[i];
                        }
                        //Also verify that all baked texture indices exist
                        foreach (byte BakedTextureIndex in AvatarAppearance.BAKE_INDICES)
                        {
                            if (BakedTextureIndex == 19) //Skirt isn't used unless you have a skirt
                                continue;
                            if (avappearance.Texture.GetFace(BakedTextureIndex).TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
                            {
                                MainConsole.Instance.Warn("[LLOGIN SERVICE]: Bad texture index for user " + account.Name + " for " + BakedTextureIndex + "!");
                                avappearance = new AvatarAppearance(account.PrincipalID);
                                m_AvatarService.SetAvatar(account.PrincipalID, new AvatarData(avappearance));
                                break;
                            }
                        }
                    }
                }
                else
                    avappearance = new AvatarAppearance(account.PrincipalID);

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

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

                // Get Friends list 
                FriendInfo[] friendsList = new FriendInfo[0];
                if (m_FriendsService != null)
                {
                    friendsList = m_FriendsService.GetFriends(account.PrincipalID);
                    //MainConsole.Instance.DebugFormat("[LLOGIN SERVICE]: Retrieved {0} friends", friendsList.Length);
                }

                //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);
                m_agentInfoService.LockLoggedInStatus (account.PrincipalID.ToString (), false); //Unlock it now
                m_agentInfoService.SetLoggedIn(account.PrincipalID.ToString(), true, true, destination.RegionID);
                
                //
                // Finally, fill out the response and return it
                //
                string MaturityRating = "A";
                string MaxMaturity = "A";
                if (agent != null)
                {
                    if (agent.MaturityRating == 0)
                        MaturityRating = "P";
                    else if (agent.MaturityRating == 1)
                        MaturityRating = "M";
                    else if (agent.MaturityRating == 2)
                        MaturityRating = "A";

                    if (agent.MaxMaturity == 0)
                        MaxMaturity = "P";
                    else if (agent.MaxMaturity == 1)
                        MaxMaturity = "M";
                    else if (agent.MaxMaturity == 2)
                        MaxMaturity = "A";
                }

                LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_InventoryService, m_LibraryService,
                    where, startLocation, position, lookAt, gestures, home, clientIP, MaxMaturity, MaturityRating,
                    eventCategories, classifiedCategories, FillOutSeedCap (aCircuit, destination, clientIP, account.PrincipalID), m_config, DisplayName, m_registry);

                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.ToString() + ".");
                AddLoginSuccessNotification(account);
                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.LockLoggedInStatus (account.PrincipalID.ToString (), false); //Unlock it now
                    m_agentInfoService.SetLoggedIn (account.PrincipalID.ToString (), false, false, UUID.Zero);
                }
                return LLFailedLoginResponse.InternalError;
            }
            
        }
Exemple #7
0
 protected bool TryFindGridRegionForAgentLogin(List<GridRegion> regions, UserAccount account,
     AvatarAppearance appearance, UUID session, UUID secureSession, uint circuitCode, Vector3 position,
     IPEndPoint clientIP, AgentCircuitData aCircuit, out GridRegion destination)
 {
     foreach (GridRegion r in regions)
     {
         string reason;
         bool success = LaunchAgentDirectly(r, ref aCircuit, out reason);
         if (success)
         {
             aCircuit = MakeAgent(r, account, appearance, session, secureSession, circuitCode, position, clientIP);
             destination = r;
             return true;
         }
         m_GridService.SetRegionUnsafe(r.RegionID);
     }
     destination = null;
     return false;
 }
        private 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++) // see note in AvatarService.cs same code there as well -VS*/
                /* Fix the use of the wrong index when locating the assets associated
                 with wearables. The fact that this hasn't caused problems earlier
                 suggests either that no one is using multiple layers of wearables or
                 that this code is useless because the assets are coming in with the
                 wearables request. Mic Bowman*/

               // for (int j = 0; j < appearance.Wearables[i].Count; j++) // added for test -VS
                {
                    if (appearance.Wearables[i][j].ItemID == UUID.Zero)
                        continue;

                    // Ignore ruth's assets
                    if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][j].ItemID)
                    {
                        //MainConsole.Instance.ErrorFormat(
                        //    "[AvatarFactory]: Found an asset for the default avatar, itemID {0}, wearable {1}, asset {2}" +
                        //    ", setting to default asset {3}.",
                        //    appearance.Wearables[i][j].ItemID, (WearableType)i, appearance.Wearables[i][j].AssetID,
                        //    AvatarWearable.DefaultWearables[i][j].AssetID);
                        appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID,
                                                    appearance.Wearables[i][j].AssetID);
                        continue;
                    }

                    if (nowWearing[i].ItemID == oldAppearance.Wearables[i][j].ItemID)
                        continue;//Don't relookup items that are the same and have already been found earlier

                    InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
                    baseItem = invService.GetItem(baseItem);

                    if (baseItem != null)
                    {
                        if (baseItem.AssetType == (int) AssetType.Link)
                        {
                            baseItem = new InventoryItemBase(baseItem.AssetID, userID);
                            baseItem = invService.GetItem(baseItem);
                        }
                        appearance.Wearables[i].Add(baseItem.ID, baseItem.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);
                    }
                }
            }
        }
        /// <summary>
        /// Saves a user's appearance
        /// </summary>
        /// <param name="agentid"></param>
        /// <param name="app"></param>
        private void HandleAppearanceSave(UUID agentid, AvatarAppearance app)
        {
            //If the avatar changes appearance, then proptly logs out, this will break!
            //ScenePresence sp = m_scene.GetScenePresence(agentid);
            //if (sp == null)
            //{
            //    MainConsole.Instance.WarnFormat("[AvatarFactory]: Agent {0} no longer in the scene", agentid);
            //    return;
            //}

            // MainConsole.Instance.WarnFormat("[AvatarFactory] avatar {0} save appearance",agentid);

            IScenePresence sp = m_scene.GetScenePresence(agentid);
            if (sp == null)
                return;

            AvatarAppearance appearance = sp != null
                                                ? sp.RequestModuleInterface<IAvatarAppearanceModule>().Appearance
                                                : app;

            m_scene.AvatarService.SetAppearance(agentid, 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();

            // 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));
        }
 public AvatarAppearance(AvatarAppearance appearance)
     : this(appearance, true)
 {
 }
 private AvatarAppearance ConvertXMLToAvatarAppearance(OSDMap map, out string FolderNameToPlaceAppearanceIn)
 {
     AvatarAppearance appearance = new AvatarAppearance();
     appearance.Unpack(map);
     FolderNameToPlaceAppearanceIn = map["FolderName"].AsString();
     return appearance;
 }
Exemple #14
0
        public LoginResponse Login(UUID AgentID, string Name, string authType, string passwd, string startLocation, UUID scopeID,
            string clientVersion, string channel, string mac, string id0, IPEndPoint clientIP, Hashtable requestData)
        {
            LoginResponse response;
            UUID session = UUID.Random();
            UUID secureSession = UUID.Zero;

            UserAccount account = AgentID != UUID.Zero ? m_UserAccountService.GetUserAccount(scopeID, AgentID) : m_UserAccountService.GetUserAccount(scopeID, Name);
            if (account == null && m_AllowAnonymousLogin)
            {
                m_UserAccountService.CreateUser(Name, passwd.StartsWith("$1$") ? passwd.Remove(0, 3):passwd, "");
                account = m_UserAccountService.GetUserAccount(scopeID, 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
                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 = 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)
                    return response;
                if (data != null)
                    secureSession = (UUID)data;//TODO: NEED TO FIND BETTER WAY TO GET THIS DATA
            }

            MainConsole.Instance.InfoFormat("[LLOGIN SERVICE]: Login request for {0} from {1} with user agent {2} starting in {3}",
                Name, clientIP.Address, clientVersion, startLocation);
            try
            {
                string DisplayName = account.Name;
                AvatarAppearance avappearance = null;
                bool newAvatar = false;
                IProfileConnector profileData = 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.SetAvatar(account.PrincipalID, new AvatarData(avappearance));
                        newAvatar = true;
                    }
                }

                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 != "")
                    {
                        AvatarAppearance appearance = m_ArchiveService.LoadAvatarArchive(archiveName, account.Name);
                        UPI.AArchiveName = "";
                        AvatarData adata = new AvatarData(appearance);
                        m_AvatarService.SetAppearance(account.PrincipalID, appearance);
                    }
                    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);

                //Reset logged in to true if the user was crashed, but don't fire the logged in event yet
                m_agentInfoService.SetLoggedIn(account.PrincipalID.ToString(), true, false, UUID.Zero);
                //Lock it as well
                m_agentInfoService.LockLoggedInStatus(account.PrincipalID.ToString(), true);
                //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(scopeID, guinfo.HomeRegionID);

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

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

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

                    m_agentInfoService.SetLastPosition(guinfo.UserID, guinfo.CurrentRegionID, guinfo.CurrentPosition, guinfo.CurrentLookAt);
                    m_agentInfoService.SetHomePosition(guinfo.UserID, guinfo.HomeRegionID, guinfo.HomePosition, guinfo.HomeLookAt);

                    MainConsole.Instance.Info("[LLLoginService]: User did not have a home, set to " +
                        (DefaultRegion == null ? "(no region found)" : DefaultRegion.RegionName));
                }

                //
                // 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, scopeID, 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;
                }

                //
                // Get the avatar
                //
                if (m_AvatarService != null)
                {
                    if(avappearance == null)
                        avappearance = m_AvatarService.GetAppearance(account.PrincipalID);
                    if (avappearance == null)
                    {
                        //Create an appearance for the user if one doesn't exist
                        if (m_DefaultUserAvatarArchive != "")
                        {
                            MainConsole.Instance.Error("[LLoginService]: Cannot find an appearance for user " + account.Name +
                                ", loading the default avatar from " + m_DefaultUserAvatarArchive + ".");
                            avappearance = m_ArchiveService.LoadAvatarArchive(m_DefaultUserAvatarArchive, account.Name);
                            m_AvatarService.SetAvatar(account.PrincipalID, new AvatarData(avappearance));
                        }
                        else
                        {
                            MainConsole.Instance.Error("[LLoginService]: Cannot find an appearance for user " + account.Name + ", setting to the default avatar.");
                            avappearance = new AvatarAppearance(account.PrincipalID);
                            m_AvatarService.SetAvatar(account.PrincipalID, new AvatarData(avappearance));
                        }
                    }
                    else
                    {
                        //Verify that all assets exist now
                        for (int i = 0; i < avappearance.Wearables.Length; i++)
                        {
                            bool messedUp = false;
                            foreach (KeyValuePair<UUID, UUID> item in avappearance.Wearables[i].GetItems())
                            {
                                AssetBase asset = m_AssetService.Get(item.Value.ToString());
                                if (asset == null)
                                {
                                    InventoryItemBase invItem = m_InventoryService.GetItem(new InventoryItemBase(item.Value));
                                    if (invItem == null)
                                    {
                                        MainConsole.Instance.Warn("[LLOGIN SERVICE]: Missing avatar appearance asset for user " + account.Name + " for item " + item.Value + ", asset should be " + item.Key + "!");
                                        messedUp = true;
                                    }
                                }
                            }
                            if (messedUp)
                                avappearance.Wearables[i] = AvatarWearable.DefaultWearables[i];
                        }
                        if (!newAvatar)
                        {
                            //Also verify that all baked texture indices exist
                            foreach (byte BakedTextureIndex in AvatarAppearance.BAKE_INDICES)
                            {
                                if (BakedTextureIndex == 19) //Skirt isn't used unless you have a skirt
                                    continue;
                                if (avappearance.Texture.GetFace(BakedTextureIndex).TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
                                {
                                    MainConsole.Instance.Warn("[LLOGIN SERVICE]: Bad texture index for user " + account.Name + " for " + BakedTextureIndex + "!");
                                    avappearance = new AvatarAppearance(account.PrincipalID);
                                    m_AvatarService.SetAvatar(account.PrincipalID, new AvatarData(avappearance));
                                    break;
                                }
                            }
                        }
                    }
                }
                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);
                    }
                }

                avappearance = FixCurrentOutFitFolder(account.PrincipalID, avappearance);
                
                //
                // Instantiate/get the simulation interface and launch an agent at the destination
                //
                string reason = string.Empty;
                AgentCircuitData aCircuit = LaunchAgentAtGrid(destination, tpFlags, account, avappearance, session, secureSession, position, where,
                    clientIP, out where, out reason, 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);
                m_agentInfoService.LockLoggedInStatus(account.PrincipalID.ToString(), false); //Unlock it now
                m_agentInfoService.SetLoggedIn(account.PrincipalID.ToString(), true, 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";
                }

                response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList.ToArray(), m_InventoryService, m_LibraryService,
                    where, startLocation, position, lookAt, gestures, home, clientIP, MaxMaturity, MaturityRating,
                    eventCategories, classifiedCategories, FillOutSeedCap(aCircuit, destination, clientIP, account.PrincipalID), m_config, DisplayName, m_registry);

                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.ToString() + ".");
                AddLoginSuccessNotification(account);
                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.LockLoggedInStatus(account.PrincipalID.ToString(), false); //Unlock it now
                    m_agentInfoService.SetLoggedIn(account.PrincipalID.ToString(), false, false, UUID.Zero);
                }
                return LLFailedLoginResponse.InternalError;
            }
        }
 protected bool TryFindGridRegionForAgentLogin(List<GridRegion> regions, UserAccount account,
     AvatarAppearance appearance, UUID session, UUID secureSession, uint circuitCode, Vector3 position,
     IPEndPoint clientIP, AgentCircuitData aCircuit, out string seedCap, out string reason, out GridRegion destination)
 {
     LoginAgentArgs args = null;
     foreach (GridRegion r in regions)
     {
         args = m_registry.RequestModuleInterface<IAgentProcessing>().
             LoginAgent(r, aCircuit);
         if (args.Success)
         {
             aCircuit = MakeAgent(r, account, appearance, session, secureSession, circuitCode, position, clientIP);
             destination = r;
             reason = args.Reason;
             seedCap = args.SeedCap;
             return true;
         }
         m_GridService.SetRegionUnsafe(r.RegionID);
     }
     if (args != null)
     {
         seedCap = args.SeedCap;
         reason = args.Reason;
     }
     else
     {
         seedCap = "";
         reason = "";
     }
     destination = null;
     return false;
 }
        public AvatarAppearance FixCurrentOutFitFolder(UUID user, AvatarAppearance avappearance)
        {
            InventoryFolderBase CurrentOutFitFolder = m_InventoryService.GetFolderForType(user, 0, AssetType.CurrentOutfitFolder);
			if (CurrentOutFitFolder == null) return avappearance;
            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 = null;
                if ((linkedItem = m_InventoryService.GetItem(new InventoryItemBase(i.AssetID))) == null)
                {
                    brokenLinks.Add(i.ID);
                }
                else if (linkedItem.ID == AvatarWearable.DEFAULT_EYES_ITEM ||
                            linkedItem.ID == AvatarWearable.DEFAULT_BODY_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 = null;
                        if ((linkedItem2 = m_InventoryService.GetItem(new InventoryItemBase(wearable[ii].ItemID))) != null)
                        {
                            InventoryItemBase linkedItem3 = (InventoryItemBase)linkedItem2.Clone();
                            linkedItem3.AssetID = linkedItem2.ID;
                            linkedItem3.AssetType = 24;
                            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<AvatarAttachment> attachments = avappearance.GetAttachments();
            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 = null;
                        if ((linkedItem2 = m_InventoryService.GetItem(new InventoryItemBase(attachment.ItemID))) != null)
                        {
                            InventoryItemBase linkedItem3 = (InventoryItemBase)linkedItem2.Clone();
                            linkedItem3.AssetID = linkedItem2.ID;
                            linkedItem3.AssetType = 24;
                            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);

            return avappearance;

        }
        /// <summary>
        /// Sends an avatars appearance (only called by the TimeSender)
        /// </summary>
        /// <param name="agentid"></param>
        /// <param name="app">ALWAYS NULL</param>
        private 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>
        // </summary>
        // <param name=""></param>
        public AvatarData GetAvatar(UUID userID)
        {
            NameValueCollection requestArgs = new NameValueCollection
                                                  {
                                                      {"RequestMethod", "GetUser"},
                                                      {"UserID", userID.ToString()}
                                                  };

            OSDMap response = WebUtils.PostToService(m_serverUrl, requestArgs);
            if (response["Success"].AsBoolean())
            {
                OSDMap map = null;
                try
                {
                    map = OSDParser.DeserializeJson(response["LLAppearance"].AsString()) as OSDMap;
                }
                catch
                {
                }

                if (map != null)
                {
                    AvatarWearable[] wearables = new AvatarWearable[13];
                    wearables[0] = new AvatarWearable(map["ShapeItem"].AsUUID(), map["ShapeAsset"].AsUUID());
                    wearables[1] = new AvatarWearable(map["SkinItem"].AsUUID(), map["SkinAsset"].AsUUID());
                    wearables[2] = new AvatarWearable(map["HairItem"].AsUUID(), map["HairAsset"].AsUUID());
                    wearables[3] = new AvatarWearable(map["EyesItem"].AsUUID(), map["EyesAsset"].AsUUID());
                    wearables[4] = new AvatarWearable(map["ShirtItem"].AsUUID(), map["ShirtAsset"].AsUUID());
                    wearables[5] = new AvatarWearable(map["PantsItem"].AsUUID(), map["PantsAsset"].AsUUID());
                    wearables[6] = new AvatarWearable(map["ShoesItem"].AsUUID(), map["ShoesAsset"].AsUUID());
                    wearables[7] = new AvatarWearable(map["SocksItem"].AsUUID(), map["SocksAsset"].AsUUID());
                    wearables[8] = new AvatarWearable(map["JacketItem"].AsUUID(), map["JacketAsset"].AsUUID());
                    wearables[9] = new AvatarWearable(map["GlovesItem"].AsUUID(), map["GlovesAsset"].AsUUID());
                    wearables[10] = new AvatarWearable(map["UndershirtItem"].AsUUID(), map["UndershirtAsset"].AsUUID());
                    wearables[11] = new AvatarWearable(map["UnderpantsItem"].AsUUID(), map["UnderpantsAsset"].AsUUID());
                    wearables[12] = new AvatarWearable(map["SkirtItem"].AsUUID(), map["SkirtAsset"].AsUUID());

                    AvatarAppearance appearance = new AvatarAppearance(userID)
                                                      {
                                                          Wearables = wearables,
                                                          AvatarHeight = (float) map["Height"].AsReal()
                                                      };

                    AvatarData avatar = new AvatarData(appearance);

                    // Get attachments
                    map = null;
                    try
                    {
                        map = OSDParser.DeserializeJson(response["LLAttachments"].AsString()) as OSDMap;
                    }
                    catch
                    {
                    }

                    if (map != null)
                    {
                        foreach (KeyValuePair<string, OSD> kvp in map)
                            avatar.Data[kvp.Key] = kvp.Value.AsString();
                    }

                    return avatar;
                }
                else
                {
                    MainConsole.Instance.Warn("[SIMIAN AVATAR CONNECTOR]: Failed to get user appearance for " + userID +
                               ", LLAppearance is missing or invalid");
                    return null;
                }
            }
            else
            {
                MainConsole.Instance.Warn("[SIMIAN AVATAR CONNECTOR]: Failed to get user appearance for " + userID + ": " +
                           response["Message"].AsString());
            }

            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">ALWAYS NULL</param>
        private 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);

            //Only set this if we actually have sent the wearables
            appearance.InitialHasWearablesBeenSent = true;

            // This agent just became root. We are going to tell everyone about it.
            appearance.SendAvatarDataToAllAgents(true);
            if (ValidateBakedTextureCache(sp.ControllingClient))
                appearance.SendAppearanceToAgent(sp);
            else
                MainConsole.Instance.ErrorFormat("[AvatarFactory]: baked textures are NOT in the cache for {0}", sp.Name);

            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>
        // </summary>
        // <param name=""></param>
        public bool SetAppearance(UUID userID, AvatarAppearance appearance)
        {
            OSDMap map = appearance.Pack();
            if (map == null)
            {
                MainConsole.Instance.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to encode appearance for {0}", userID);
                return false;
            }

            // DEBUG ON
            MainConsole.Instance.WarnFormat("[SIMIAN AVATAR CONNECTOR] save appearance for {0}", userID);
            // DEBUG OFF

            NameValueCollection requestArgs = new NameValueCollection
                                                  {
                                                      {"RequestMethod", "AddUserData"},
                                                      {"UserID", userID.ToString()},
                                                      {"LLPackedAppearance", OSDParser.SerializeJsonString(map)}
                                                  };

            OSDMap response = WebUtils.PostToService(m_serverUrl, requestArgs);
            bool success = response["Success"].AsBoolean();

            if (!success)
                MainConsole.Instance.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to save appearance for {0}: {1}",
                                 userID, response["Message"].AsString());

            return success;
        }
Exemple #21
0
        protected AgentCircuitData LaunchAgentAtGrid(GridRegion destination, TeleportFlags tpFlags, UserAccount account, AvatarAppearance appearance,
            UUID session, UUID secureSession, Vector3 position, string currentWhere,
            IPEndPoint clientIP, out string where, out string reason, out GridRegion dest)
        {
            where = currentWhere;
            reason = string.Empty;
            uint circuitCode = 0;
            AgentCircuitData aCircuit = null;
            dest = destination;

            bool success = false;

            #region Launch Agent

            circuitCode = (uint)Util.RandomClass.Next();
            aCircuit = MakeAgent(destination, account, appearance, session, secureSession, circuitCode, position, clientIP);
            aCircuit.teleportFlags = (uint)tpFlags;
            success = LaunchAgentDirectly(destination, ref aCircuit, out reason);
            if (!success && m_GridService != null)
            {
                //Remove the landmark flag (landmark is used for ignoring the landing points in the region)
                aCircuit.teleportFlags &= ~(uint)TeleportFlags.ViaLandmark;
                m_GridService.SetRegionUnsafe(destination.RegionID);

                // Make sure the client knows this isn't where they wanted to land
                where = "safe";

                // Try the default regions
                List<GridRegion> defaultRegions = m_GridService.GetDefaultRegions(account.ScopeID);
                if (defaultRegions != null)
                {
                    success = TryFindGridRegionForAgentLogin(defaultRegions, account,
                        appearance, session, secureSession, circuitCode, position,
                        clientIP, aCircuit, out dest);
                }
                if (!success)
                {
                    // Try the fallback regions
                    List<GridRegion> fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY);
                    if (fallbacks != null)
                    {
                        success = TryFindGridRegionForAgentLogin(fallbacks, account,
                            appearance, session, secureSession, circuitCode, position,
                            clientIP, aCircuit, out dest);
                    }
                    if (!success)
                    {
                        //Try to find any safe region
                        List<GridRegion> safeRegions = m_GridService.GetSafeRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY);
                        if (safeRegions != null)
                        {
                            success = TryFindGridRegionForAgentLogin(safeRegions, account,
                                appearance, session, secureSession, circuitCode, position,
                                clientIP, aCircuit, out dest);
                            if (!success)
                                reason = "No Region Found";
                        }
                    }
                }
            }

            #endregion

            if (success)
            {
                //Set the region to safe since we got there
                m_GridService.SetRegionSafe (destination.RegionID);
                return aCircuit;
            }
            return null;
        }
        // <summary>
        // Retrieves the LLPackedAppearance field from user data and unpacks
        // it into an AvatarAppearance structure
        // </summary>
        // <param name="userID"></param>
        public AvatarAppearance GetAppearance(UUID userID)
        {
            NameValueCollection requestArgs = new NameValueCollection
                                                  {
                                                      {"RequestMethod", "GetUser"},
                                                      {"UserID", userID.ToString()}
                                                  };

            OSDMap response = WebUtils.PostToService(m_serverUrl, requestArgs);
            if (response["Success"].AsBoolean())
            {
                OSDMap map = null;
                try
                {
                    map = OSDParser.DeserializeJson(response["LLPackedAppearance"].AsString()) as OSDMap;
                }
                catch
                {
                }

                if (map != null)
                {
                    AvatarAppearance appearance = new AvatarAppearance(map);
                    // DEBUG ON
                    MainConsole.Instance.WarnFormat("[SIMIAN AVATAR CONNECTOR] retrieved appearance for {0}:\n{1}", userID, appearance);
                    // DEBUG OFF
                    return appearance;
                }

                MainConsole.Instance.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to decode appearance for {0}", userID);
                return null;
            }

            MainConsole.Instance.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to get appearance for {0}: {1}",
                             userID, response["Message"].AsString());
            return null;
        }
Exemple #23
0
        protected AgentCircuitData MakeAgent(GridRegion region, UserAccount account,
            AvatarAppearance appearance, UUID session, UUID secureSession, uint circuit, Vector3 position,
            IPEndPoint clientIP)
        {
            AgentCircuitData aCircuit = new AgentCircuitData
                                            {
                                                AgentID = account.PrincipalID,
                                                Appearance = appearance ?? new AvatarAppearance(account.PrincipalID),
                                                CapsPath = CapsUtil.GetRandomCapsObjectPath(),
                                                child = false,
                                                circuitcode = circuit,
                                                SecureSessionID = secureSession,
                                                SessionID = session,
                                                startpos = position,
                                                IPAddress = clientIP.Address.ToString(),
                                                ClientIPEndPoint = clientIP
                                            };


            // the first login agent is root

            return aCircuit;
        }
        /// <summary>
        /// This method is called by establishAppearance to do a copy all inventory items
        /// worn or attached to the Clothing inventory folder of the receiving avatar.
        /// In parallel the avatar wearables and attachments are updated.
        /// </summary>

        private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance)
        {
            IInventoryService inventoryService = manager.CurrentOrFirstScene.InventoryService;

            // Get Clothing folder of receiver
            InventoryFolderBase destinationFolder = inventoryService.GetFolderForType (destination, InventoryType.Wearable, AssetType.Clothing);

            if (destinationFolder == null)
                throw new Exception("Cannot locate folder(s)");

            // Missing destination folder? This should *never* be the case
            if (destinationFolder.Type != (short)AssetType.Clothing)
            {
                destinationFolder = new InventoryFolderBase
                                        {
                                            ID = UUID.Random(),
                                            Name = "Clothing",
                                            Owner = destination,
                                            Type = (short) AssetType.Clothing,
                                            ParentID = inventoryService.GetRootFolder(destination).ID,
                                            Version = 1
                                        };

                inventoryService.AddFolder(destinationFolder);     // store base record
                MainConsole.Instance.ErrorFormat("[RADMIN] Created folder for destination {0}", source);
            }

            // Wearables
            AvatarWearable[] wearables = avatarAppearance.Wearables;

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

                    if (item != null)
                    {
                        InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination)
                                                                {
                                                                    Name = item.Name,
                                                                    Description = item.Description,
                                                                    InvType = item.InvType,
                                                                    CreatorId = item.CreatorId,
                                                                    CreatorData = item.CreatorData,
                                                                    CreatorIdAsUuid = item.CreatorIdAsUuid,
                                                                    NextPermissions = item.NextPermissions,
                                                                    CurrentPermissions = item.CurrentPermissions,
                                                                    BasePermissions = item.BasePermissions,
                                                                    EveryOnePermissions = item.EveryOnePermissions,
                                                                    GroupPermissions = item.GroupPermissions,
                                                                    AssetType = item.AssetType,
                                                                    AssetID = item.AssetID,
                                                                    GroupID = item.GroupID,
                                                                    GroupOwned = item.GroupOwned,
                                                                    SalePrice = item.SalePrice,
                                                                    SaleType = item.SaleType,
                                                                    Flags = item.Flags,
                                                                    CreationDate = item.CreationDate,
                                                                    Folder = destinationFolder.ID
                                                                };
                        ILLClientInventory inventoryModule = manager.CurrentOrFirstScene.RequestModuleInterface<ILLClientInventory>();
                        if (inventoryModule != null)
                            inventoryModule.AddInventoryItem(destinationItem);
                        MainConsole.Instance.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);

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

            // Attachments
            List<AvatarAttachment> attachments = avatarAppearance.GetAttachments();

            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 = new InventoryItemBase(itemID, source);
                    item = inventoryService.GetItem(item);

                    if (item != null)
                    {
                        InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination)
                                                                {
                                                                    Name = item.Name,
                                                                    Description = item.Description,
                                                                    InvType = item.InvType,
                                                                    CreatorId = item.CreatorId,
                                                                    CreatorData = item.CreatorData,
                                                                    CreatorIdAsUuid = item.CreatorIdAsUuid,
                                                                    NextPermissions = item.NextPermissions,
                                                                    CurrentPermissions = item.CurrentPermissions,
                                                                    BasePermissions = item.BasePermissions,
                                                                    EveryOnePermissions = item.EveryOnePermissions,
                                                                    GroupPermissions = item.GroupPermissions,
                                                                    AssetType = item.AssetType,
                                                                    AssetID = item.AssetID,
                                                                    GroupID = item.GroupID,
                                                                    GroupOwned = item.GroupOwned,
                                                                    SalePrice = item.SalePrice,
                                                                    SaleType = item.SaleType,
                                                                    Flags = item.Flags,
                                                                    CreationDate = item.CreationDate,
                                                                    Folder = destinationFolder.ID
                                                                };
                        ILLClientInventory inventoryModule = manager.CurrentOrFirstScene.RequestModuleInterface<ILLClientInventory>();
                        if (inventoryModule != null)
                            inventoryModule.AddInventoryItem(destinationItem);
                        MainConsole.Instance.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);

                        // Attach item
                        avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID);
                        MainConsole.Instance.DebugFormat("[RADMIN]: Attached {0}", destinationItem.ID);
                    }
                    else
                    {
                        MainConsole.Instance.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID);
                    }
                }
            }
        }
        public AvatarData(AvatarAppearance appearance)
        {
            AvatarType = 1; // SL avatars
            Data = new Dictionary<string, string>();

            Data["Serial"] = appearance.Serial.ToString();
            // Wearables
            Data["AvatarHeight"] = appearance.AvatarHeight.ToString();

            Data["Textures"] = OSDParser.SerializeJsonString(appearance.Texture.GetOSD());

            for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
            {
                for (int j = 0; j < appearance.Wearables[i].Count; j++)
                {
                    string fieldName = String.Format("Wearable {0}:{1}", i, j);
                    Data[fieldName] = String.Format("{0}:{1}",
                                                    appearance.Wearables[i][j].ItemID.ToString(),
                                                    appearance.Wearables[i][j].AssetID.ToString());
                }
            }

            // Visual Params
            string[] vps = new string[AvatarAppearance.VISUALPARAM_COUNT];
            byte[] binary = appearance.VisualParams;

            for (int i = 0; i < AvatarAppearance.VISUALPARAM_COUNT; i++)
            {
                vps[i] = binary[i].ToString();
            }

            Data["VisualParams"] = String.Join(",", vps);

            // Attachments
            List<AvatarAttachment> attachments = appearance.GetAttachments();
            foreach (AvatarAttachment attach in attachments)
            {
                Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
                Data["_apa_" + attach.AttachPoint] = attach.AssetID.ToString();
            }
        }
        /// <summary>
        /// This method is called by establishAppearance to copy inventory folders to make
        /// copies of Clothing and Bodyparts inventory folders and attaches worn attachments
        /// </summary>

        private void CopyInventoryFolders(UUID destination, UUID source, AssetType assetType, Dictionary<UUID,UUID> inventoryMap,
                                          AvatarAppearance avatarAppearance)
        {
            IInventoryService inventoryService = manager.CurrentOrFirstScene.InventoryService;

            InventoryFolderBase sourceFolder = inventoryService.GetFolderForType(source, InventoryType.Unknown, assetType);
            InventoryFolderBase destinationFolder = inventoryService.GetFolderForType (destination, InventoryType.Unknown, assetType);

            if (sourceFolder == null || destinationFolder == null)
                throw new Exception("Cannot locate folder(s)");

            // Missing source folder? This should *never* be the case
            if (sourceFolder.Type != (short)assetType)
            {
                sourceFolder = new InventoryFolderBase
                                   {
                                       ID = UUID.Random(),
                                       Name = assetType == AssetType.Clothing ? "Clothing" : "Body Parts",
                                       Owner = source,
                                       Type = (short) assetType,
                                       ParentID = inventoryService.GetRootFolder(source).ID,
                                       Version = 1
                                   };
                inventoryService.AddFolder(sourceFolder);     // store base record
                MainConsole.Instance.ErrorFormat("[RADMIN] Created folder for source {0}", source);
            }

            // Missing destination folder? This should *never* be the case
            if (destinationFolder.Type != (short)assetType)
            {
                destinationFolder = new InventoryFolderBase
                                        {
                                            ID = UUID.Random(),
                                            Name = assetType.ToString(),
                                            Owner = destination,
                                            Type = (short) assetType,
                                            ParentID = inventoryService.GetRootFolder(destination).ID,
                                            Version = 1
                                        };
                inventoryService.AddFolder(destinationFolder);     // store base record
                MainConsole.Instance.ErrorFormat("[RADMIN] Created folder for destination {0}", source);
            }

            List<InventoryFolderBase> folders = inventoryService.GetFolderContent(source, sourceFolder.ID).Folders;

            foreach (InventoryFolderBase folder in folders)
            {

                InventoryFolderBase extraFolder = new InventoryFolderBase
                                                      {
                                                          ID = UUID.Random(),
                                                          Name = folder.Name,
                                                          Owner = destination,
                                                          Type = folder.Type,
                                                          Version = folder.Version,
                                                          ParentID = destinationFolder.ID
                                                      };
                inventoryService.AddFolder(extraFolder);

                MainConsole.Instance.DebugFormat("[RADMIN] Added folder {0} to folder {1}", extraFolder.ID, sourceFolder.ID);

                List<InventoryItemBase> items = inventoryService.GetFolderContent(source, folder.ID).Items;

                foreach (InventoryItemBase item in items)
                {
                    InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination)
                                                            {
                                                                Name = item.Name,
                                                                Description = item.Description,
                                                                InvType = item.InvType,
                                                                CreatorId = item.CreatorId,
                                                                CreatorData = item.CreatorData,
                                                                CreatorIdAsUuid = item.CreatorIdAsUuid,
                                                                NextPermissions = item.NextPermissions,
                                                                CurrentPermissions = item.CurrentPermissions,
                                                                BasePermissions = item.BasePermissions,
                                                                EveryOnePermissions = item.EveryOnePermissions,
                                                                GroupPermissions = item.GroupPermissions,
                                                                AssetType = item.AssetType,
                                                                AssetID = item.AssetID,
                                                                GroupID = item.GroupID,
                                                                GroupOwned = item.GroupOwned,
                                                                SalePrice = item.SalePrice,
                                                                SaleType = item.SaleType,
                                                                Flags = item.Flags,
                                                                CreationDate = item.CreationDate,
                                                                Folder = extraFolder.ID
                                                            };

                    ILLClientInventory inventoryModule = manager.CurrentOrFirstScene.RequestModuleInterface<ILLClientInventory>();
                    if (inventoryModule != null)
                        inventoryModule.AddInventoryItem(destinationItem);
                    inventoryMap.Add(item.ID, destinationItem.ID);
                    MainConsole.Instance.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, extraFolder.ID);

                    // Attach item, if original is attached
                    int attachpoint = avatarAppearance.GetAttachpoint(item.ID);
                    if (attachpoint != 0)
                    {
                        avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID);
                        MainConsole.Instance.DebugFormat("[RADMIN]: Attached {0}", destinationItem.ID);
                    }
                }
            }
        }
        /// <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);

            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,
                                                                                                       AssetType.
                                                                                                           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,
                                                                                                       AssetType.
                                                                                                           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.FillHash();
                            asset.ID = m_scene.AssetService.Store(asset);
                            m_underPantsUUID = asset.ID;
                        }
                        item.CreatorId = UUID.Zero.ToString();
                        item.AssetID = m_underPantsUUID;
                        m_scene.InventoryService.AddItem(item);
                        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,
                                                                                                       AssetType.
                                                                                                           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,
                                                                                                       AssetType.
                                                                                                           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.FillHash();
                            asset.ID = m_scene.AssetService.Store(asset);
                            m_underShirtUUID = asset.ID;
                        }
                        item.CreatorId = UUID.Zero.ToString();
                        item.AssetID = m_underShirtUUID;
                        m_scene.InventoryService.AddItem(item);
                        client.SendInventoryItemCreateUpdate(item, 0);
                        wear.ItemID = item.ID;
                    }
                }
            }

#if (!ISWIN)
            foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
            {
                if (wear.Type < AvatarWearable.MAX_WEARABLES)
                {
                    /*if (incomingLinks.ContainsKey (wear.ItemID))
                    {
                        wear.ItemID = incomingLinks[wear.ItemID];
                    }*/
                    avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
                }
            }
#else
            foreach (AvatarWearingArgs.Wearable wear in e.NowWearing.Where(wear => wear.Type < AvatarWearable.MAX_WEARABLES))
            {
                avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
            }
#endif

            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;
            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
#if (!ISWIN)
                foreach (Primitive.TextureEntryFace t in appearance.Appearance.Texture.FaceTextures)
                {
                    Primitive.TextureEntryFace face = (t);
                    if (face != null)
                    {
                        sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
                    }
                }
#else
                foreach (Primitive.TextureEntryFace face in appearance.Appearance.Texture.FaceTextures.Select(t => (t)).Where(face => face != null))
                {
                    sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
                }
#endif
            }
            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,
                                                                                           AssetType.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 = (InventoryItemBase) itemBase.Clone();
                    newcopy.ID = UUID.Random();
                    newcopy.Folder = folderForAppearance.ID;
                    newcopy.Owner = user;
                    m_InventoryService.AddItem(newcopy);

                    if (newcopy.InvType == (int) InventoryType.Object)
                    {
                        AssetBase attobj = m_AssetService.Get(newcopy.AssetID.ToString());

                        if (attobj != null)
                        {
                            string xmlData = Utils.BytesToString(attobj.Data);
                            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;
                            }
                        }
                    }
                }
            }
            return avappearance;
        }
 public bool SetAppearance(UUID principalID, AvatarAppearance appearance)
 {
     AvatarData avatar = new AvatarData(appearance);
     return SetAvatar(principalID, avatar);
 }
        private AvatarAppearance CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance, InventoryFolderBase destinationFolder)
        {
            if (destinationFolder == null)
                throw new Exception("Cannot locate folder(s)");

            // Wearables
            AvatarWearable[] wearables = avatarAppearance.Wearables;

            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 = new InventoryItemBase(wearable[ii].ItemID);
                        item = InventoryService.GetItem(item);

                        if (item != null)
                        {
                            InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination)
                                                                    {
                                                                        Name = item.Name,
                                                                        Description = item.Description,
                                                                        InvType = item.InvType,
                                                                        CreatorId = item.CreatorId,
                                                                        CreatorData = item.CreatorData,
                                                                        CreatorIdAsUuid = item.CreatorIdAsUuid,
                                                                        NextPermissions = item.NextPermissions,
                                                                        CurrentPermissions = item.CurrentPermissions,
                                                                        BasePermissions = item.BasePermissions,
                                                                        EveryOnePermissions = item.EveryOnePermissions,
                                                                        GroupPermissions = item.GroupPermissions,
                                                                        AssetType = item.AssetType,
                                                                        AssetID = item.AssetID,
                                                                        GroupID = item.GroupID,
                                                                        GroupOwned = item.GroupOwned,
                                                                        SalePrice = item.SalePrice,
                                                                        SaleType = item.SaleType,
                                                                        Flags = item.Flags,
                                                                        CreationDate = item.CreationDate,
                                                                        Folder = destinationFolder.ID
                                                                    };
                            if (InventoryService != null)
                                InventoryService.AddItem(destinationItem);
                            MainConsole.Instance.DebugFormat("[RADMIN]: Added item {0} to folder {1}",
                                                             destinationItem.ID, destinationFolder.ID);

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

            // Attachments
            List<AvatarAttachment> attachments = avatarAppearance.GetAttachments();

            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 = new InventoryItemBase(itemID, source);
                    item = InventoryService.GetItem(item);

                    if (item != null)
                    {
                        InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination)
                        {
                            Name = item.Name,
                            Description = item.Description,
                            InvType = item.InvType,
                            CreatorId = item.CreatorId,
                            CreatorData = item.CreatorData,
                            CreatorIdAsUuid = item.CreatorIdAsUuid,
                            NextPermissions = item.NextPermissions,
                            CurrentPermissions = item.CurrentPermissions,
                            BasePermissions = item.BasePermissions,
                            EveryOnePermissions = item.EveryOnePermissions,
                            GroupPermissions = item.GroupPermissions,
                            AssetType = item.AssetType,
                            AssetID = item.AssetID,
                            GroupID = item.GroupID,
                            GroupOwned = item.GroupOwned,
                            SalePrice = item.SalePrice,
                            SaleType = item.SaleType,
                            Flags = item.Flags,
                            CreationDate = item.CreationDate,
                            Folder = destinationFolder.ID
                        };
                        if (InventoryService != null)
                            InventoryService.AddItem(destinationItem);
                        MainConsole.Instance.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);

                        // Attach item
                        avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID);
                        MainConsole.Instance.DebugFormat("[RADMIN]: Attached {0}", destinationItem.ID);
                    }
                    else
                    {
                        MainConsole.Instance.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID);
                    }
                }
            }
            return avatarAppearance;
        }