Exemplo n.º 1
0
 protected override bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response, string clientVersion)
 {
     return PrepareLoginToRegion(RegionProfileData.FromRegionInfo(regionInfo), user, response, clientVersion);
 }
Exemplo n.º 2
0
        /// <summary>
        /// Prepare a login to the given region.  This involves both telling the region to expect a connection
        /// and appropriately customising the response to the user.
        /// </summary>
        /// <param name="regionInfo"></param>
        /// <param name="user"></param>
        /// <param name="response"></param>
        /// <returns>true if the region was successfully contacted, false otherwise</returns>
        private bool PrepareLoginToRegion(RegionProfileData regionInfo, UserProfileData user, LoginResponse response, string clientVersion)
        {
            string regionName = regionInfo.regionName;
            bool success = false;

            try
            {
                lock (_LastRegionFailure)
                {
                    if (_LastRegionFailure.ContainsKey(regionName))
                    {
                        // region failed previously
                        RegionLoginFailure failure = _LastRegionFailure[regionName];
                        if (failure.IsExpired())
                        {
                            // failure has expired, retry this region again
                            _LastRegionFailure.Remove(regionName);
//                            m_log.WarnFormat("[LOGIN]: Region '{0}' was previously down, retrying.", regionName);
                        }
                        else
                        {
                            if (failure.IsFailed())
                            {
//                                m_log.WarnFormat("[LOGIN]: Region '{0}' was recently down, skipping.", regionName);
                                return false;   // within 5 minutes, don't repeat attempt
                            }
//                            m_log.WarnFormat("[LOGIN]: Region '{0}' was recently down but under threshold, retrying.", regionName);
                        }
                    }
                }

                response.SimAddress = regionInfo.OutsideIpOrResolvedHostname;
                response.SimPort = regionInfo.serverPort;
                response.RegionX = regionInfo.regionLocX;
                response.RegionY = regionInfo.regionLocY;

                string capsPath = CapsUtil.GetRandomCapsObjectPath();

                response.SeedCapability = CapsUtil.GetFullCapsSeedURL(regionInfo.httpServerURI, capsPath);

                // Notify the target of an incoming user
                m_log.InfoFormat(
                    "[LOGIN]: Telling {0} @ {1},{2} ({3}) to prepare for client connection",
                    regionInfo.regionName, response.RegionX, response.RegionY, response.SeedCapability);

                // Update agent with target sim
                user.CurrentAgent.Region = regionInfo.UUID;
                user.CurrentAgent.Handle = regionInfo.regionHandle;

                // Prepare notification
                Hashtable loginParams = new Hashtable();
                loginParams["session_id"] = user.CurrentAgent.SessionID.ToString();
                loginParams["secure_session_id"] = user.CurrentAgent.SecureSessionID.ToString();
                loginParams["firstname"] = user.FirstName;
                loginParams["lastname"] = user.SurName;
                loginParams["agent_id"] = user.ID.ToString();
                loginParams["circuit_code"] = (Int32)Convert.ToUInt32(response.CircuitCode);
                loginParams["startpos_x"] = user.CurrentAgent.Position.X.ToString();
                loginParams["startpos_y"] = user.CurrentAgent.Position.Y.ToString();
                loginParams["startpos_z"] = user.CurrentAgent.Position.Z.ToString();
                loginParams["regionhandle"] = user.CurrentAgent.Handle.ToString();
                loginParams["caps_path"] = capsPath;
                loginParams["client_version"] = clientVersion;

                // Get appearance
                AvatarAppearance appearance = m_userManager.GetUserAppearance(user.ID);
                if (appearance != null)
                {
                    loginParams["appearance"] = appearance.ToHashTable();
                    m_log.DebugFormat("[LOGIN]: Found appearance version {0} for {1} {2}", appearance.Serial, user.FirstName, user.SurName);
                }
                else
                {
                    m_log.DebugFormat("[LOGIN]: Appearance not for {0} {1}. Creating default.", user.FirstName, user.SurName);
                    appearance = new AvatarAppearance(user.ID);
                }

                // Tell the client the COF version so it can use cached appearance if it matches.
                response.CofVersion = appearance.Serial.ToString();
                loginParams["cof_version"] = response.CofVersion;

                ArrayList SendParams = new ArrayList();
                SendParams.Add(loginParams);
                SendParams.Add(m_config.GridSendKey);

                // Send
                const string METHOD_NAME = "expect_user";
                XmlRpcRequest GridReq = new XmlRpcRequest(METHOD_NAME, SendParams);
                XmlRpcResponse GridResp = GridReq.Send(Util.XmlRpcRequestURI(regionInfo.httpServerURI, METHOD_NAME), 6000);

                if (!GridResp.IsFault)
                {
                    bool responseSuccess = true;

                    if (GridResp.Value != null)
                    {
                        Hashtable resp = (Hashtable)GridResp.Value;
                        if (resp.ContainsKey("success"))
                        {
                            if ((string)resp["success"] == "FALSE")
                            {
                                responseSuccess = false;
                            }
                        }
                        if (!responseSuccess)
                        {
                            if (resp.ContainsKey("reason"))
                            {
                                response.ErrorMessage = resp["reason"].ToString();
                            }
                        }
                    }
                    
                    if (responseSuccess)
                    {
                        handlerUserLoggedInAtLocation = OnUserLoggedInAtLocation;
                        if (handlerUserLoggedInAtLocation != null)
                        {
                            handlerUserLoggedInAtLocation(user.ID, user.CurrentAgent.SessionID,
                                                          user.CurrentAgent.Region,
                                                          user.CurrentAgent.Handle,
                                                          user.CurrentAgent.Position.X,
                                                          user.CurrentAgent.Position.Y,
                                                          user.CurrentAgent.Position.Z,
                                                          user.FirstName, user.SurName);
                        }
                        success = true;
                    }
                    else
                    {
                        m_log.ErrorFormat("[LOGIN]: Region responded that it is not available to receive clients");
                    }
                }
                else
                {
                    m_log.ErrorFormat("[LOGIN]: XmlRpc request to region failed with message {0}, code {1} ", GridResp.FaultString, GridResp.FaultCode);
                }
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("[LOGIN]: Region not available for login, {0}", e);
            }

            lock (_LastRegionFailure)
            {
                if (_LastRegionFailure.ContainsKey(regionName))
                {
                    RegionLoginFailure failure = _LastRegionFailure[regionName];
                    if (success)
                    {   // Success, so if we've been storing this as a failed region, remove that from the failed list.
                        m_log.WarnFormat("[LOGIN]: Region '{0}' recently down, is available again.", regionName);
                        _LastRegionFailure.Remove(regionName);
                    }
                    else
                    {
                        // Region not available, update cache with incremented count.
                        failure.AddFailure();
//                        m_log.WarnFormat("[LOGIN]: Region '{0}' is still down ({1}).", regionName, failure.Count);
                    }
                }
                else
                {
                    if (!success)
                    {
                        // Region not available, cache that temporarily.
                        m_log.WarnFormat("[LOGIN]: Region '{0}' is down, marking.", regionName);
                        _LastRegionFailure[regionName] = new RegionLoginFailure();
                    }
                }
            }
            return success;
        }
Exemplo n.º 3
0
        // For returning users' where the preferred region is down
        protected bool PrepareNextDefaultRegion(LoginResponse response, UserProfileData theUser, string clientVersion)
		{
            return PrepareNextRegion(response, theUser, _DefaultRegionsList, "safe", clientVersion);
		}
Exemplo n.º 4
0
        /// <summary>
        /// Customises the login response and fills in missing values.  This method also tells the login region to
        /// expect a client connection.
        /// </summary>
        /// <param name="response">The existing response</param>
        /// <param name="theUser">The user profile</param>
        /// <param name="startLocationRequest">The requested start location</param>
        /// <returns>true on success, false if the region was not successfully told to expect a user connection</returns>
        public bool CustomiseResponse(LoginResponse response, UserProfileData theUser, string startLocationRequest, string clientVersion)
        {
            // add active gestures to login-response
            AddActiveGestures(response, theUser);

            // HomeLocation
            RegionInfo homeInfo = null;

            // use the homeRegionID if it is stored already. If not, use the regionHandle as before
            UUID homeRegionId = theUser.HomeRegionID;
            ulong homeRegionHandle = theUser.HomeRegion;
            if (homeRegionId != UUID.Zero)
            {
                homeInfo = GetRegionInfo(homeRegionId);
            }
            else
            {
                homeInfo = GetRegionInfo(homeRegionHandle);
            }

            if (homeInfo != null)
            {
                response.Home =
                    string.Format(
                        "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
                        (homeInfo.RegionLocX * Constants.RegionSize),
                        (homeInfo.RegionLocY * Constants.RegionSize),
                        theUser.HomeLocation.X, theUser.HomeLocation.Y, theUser.HomeLocation.Z,
                        theUser.HomeLookAt.X, theUser.HomeLookAt.Y, theUser.HomeLookAt.Z);
            }
            else
            {
                m_log.InfoFormat("not found the region at {0} {1}", theUser.HomeRegionX, theUser.HomeRegionY);
                // Emergency mode: Home-region isn't available, so we can't request the region info.
                // Use the stored home regionHandle instead.
                // NOTE: If the home-region moves, this will be wrong until the users update their user-profile again
                ulong regionX = homeRegionHandle >> 32;
                ulong regionY = homeRegionHandle & 0xffffffff;
                response.Home =
                    string.Format(
                        "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
                        regionX, regionY,
                        theUser.HomeLocation.X, theUser.HomeLocation.Y, theUser.HomeLocation.Z,
                        theUser.HomeLookAt.X, theUser.HomeLookAt.Y, theUser.HomeLookAt.Z);

                m_log.InfoFormat("[LOGIN] Home region of user {0} {1} is not available; using computed region position {2} {3}",
                                 theUser.FirstName, theUser.SurName,
                                 regionX, regionY);
            }

            // StartLocation
            RegionInfo regionInfo = null;
            if (theUser.LastLogin == 0)
            {
                // New user first login
                if (PrepareNextDefaultLogin(response, theUser, startLocationRequest, clientVersion))
                    return true;
            }
            else
            {
                // Returning user login
                if (startLocationRequest == "home")
                {
                    regionInfo = homeInfo;
                    theUser.CurrentAgent.Position = theUser.HomeLocation;
                    response.LookAt = String.Format("[r{0},r{1},r{2}]", theUser.HomeLookAt.X.ToString(),
                                                    theUser.HomeLookAt.Y.ToString(), theUser.HomeLookAt.Z.ToString());
                }
                else if (startLocationRequest == "last")
                {
                    UUID lastRegion = theUser.CurrentAgent.Region;
                    regionInfo = GetRegionInfo(lastRegion);
                    response.LookAt = String.Format("[r{0},r{1},r{2}]", theUser.CurrentAgent.LookAt.X.ToString(),
                                                    theUser.CurrentAgent.LookAt.Y.ToString(), theUser.CurrentAgent.LookAt.Z.ToString());
                }
                else
                {
                    // Logging in to a specific URL... try to find the region
                    Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
                    if (PrepareLoginToREURI(reURI, response, theUser, startLocationRequest, "url", "Custom Login URL", clientVersion))
                        return true;
                }

                // Logging in to home or last... try to find the region
                if ((regionInfo != null) && (PrepareLoginToRegion(regionInfo, theUser, response, clientVersion)))
                {
                    return true;
                }

                // StartLocation not available, send him to a nearby region instead
                // regionInfo = m_gridService.RequestClosestRegion("");
                //m_log.InfoFormat("[LOGIN]: StartLocation not available sending to region {0}", regionInfo.regionName);

                // Normal login failed, try to find a default region from the list
                if (PrepareNextDefaultRegion(response, theUser, clientVersion))
                    return true;
            }

            // No default regions available either.
			// Send him to global default region home location instead (e.g. 1000,1000)
            ulong defaultHandle = (((ulong)m_defaultHomeX * Constants.RegionSize) << 32) |
                                  ((ulong)m_defaultHomeY * Constants.RegionSize);

            if ((regionInfo != null) && (defaultHandle == regionInfo.RegionHandle))
            {
                m_log.ErrorFormat("[LOGIN]: Not trying the default region since this is the same as the selected region");
                return false;
            }

            m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead");
            regionInfo = GetRegionInfo(defaultHandle);

            if (regionInfo == null)
            {
                m_log.ErrorFormat("[LOGIN]: No default region available. Aborting.");
                return false;
            }

            theUser.CurrentAgent.Position = new Vector3(128, 128, 0);
            response.StartLocation = "safe";

            return PrepareLoginToRegion(regionInfo, theUser, response, clientVersion);
        }
Exemplo n.º 5
0
        protected bool PrepareNextRegion(LoginResponse response, UserProfileData theUser, List<string> theList, string startLocationRequest, string clientVersion)
        {
            Regex reURI = new Regex(@"^(?<region>[^&]+)/(?<x>\d+)/(?<y>\d+)/(?<z>\d+)$");
            if ((startLocationRequest != "home") && (startLocationRequest != "last"))
                startLocationRequest = "safe";

            foreach (string location in theList)
            {
                if (PrepareLoginToREURI(reURI, response, theUser, location, "safe", "default region", clientVersion))
                    return true;
            }
            return false;
        }
Exemplo n.º 6
0
        // For new users' first-time logins
        protected bool PrepareNextDefaultLogin(LoginResponse response, UserProfileData theUser, string startLocationRequest, string clientVersion)
		{
            return PrepareNextRegion(response, theUser, _DefaultLoginsList, startLocationRequest, clientVersion);
		}
Exemplo n.º 7
0
        /// <summary>
        /// Called when we receive the client's initial XMLRPC login_to_simulator request message
        /// </summary>
        /// <param name="request">The XMLRPC request</param>
        /// <returns>The response to send</returns>
        public virtual XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request, IPEndPoint remoteClient)
        {
            string loginUsername = null;

            try
            {
                XmlRpcResponse response = new XmlRpcResponse();
                Hashtable requestData = (Hashtable)request.Params[0];

                SniffLoginKey((Uri)request.Params[2], requestData);

                bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") &&
                                (requestData.Contains("passwd") || requestData.Contains("web_login_key")));

                string firstname = null;
                string lastname = null;
                LoginResponse logResponse = new LoginResponse();

                if (GoodXML)
                {
                    //make sure the user isn't already trying to log in

                    firstname = (string)requestData["first"];
                    lastname = (string)requestData["last"];

                    loginUsername = firstname + " " + lastname;

                    lock (_loginsProcessing)
                    {
                        if (_loginsProcessing.Contains(loginUsername))
                        {
                            return logResponse.CreateAlreadyLoggedInResponse();
                        }
                        else
                        {
                            _loginsProcessing.Add(loginUsername);
                        }
                    }
                }

                string startLocationRequest = "last";

                UserProfileData userProfile;
                
                string clientVersion = "Unknown";

                if (GoodXML)
                {
                    if (requestData.Contains("start"))
                    {
                        startLocationRequest = (string)requestData["start"];
                    }

                    m_log.InfoFormat(
                        "[LOGIN BEGIN]: XMLRPC Received login request message from user '{0}' '{1}'",
                        firstname, lastname);

                    if (requestData.Contains("version"))
                    {
                        clientVersion = (string)requestData["version"];
                    }

                    if (this.IsViewerBlacklisted(clientVersion))
                    {
                        m_log.DebugFormat("[LOGIN]: Denying login, Client {0} is blacklisted", clientVersion);
                        return logResponse.CreateViewerNotAllowedResponse();
                    }

                    m_log.DebugFormat(
                        "[LOGIN]: XMLRPC Client is {0}, start location is {1}", clientVersion, startLocationRequest);

                    if (!TryAuthenticateXmlRpcLogin(request, firstname, lastname, out userProfile))
                    {
                        return logResponse.CreateLoginFailedResponse();
                    }
                }
                else
                {
                    m_log.Info("[LOGIN END]: XMLRPC login_to_simulator login message did not contain all the required data");

                    return logResponse.CreateGridErrorResponse();
                }

                if (userProfile.GodLevel < m_minLoginLevel)
                {
                    return logResponse.CreateLoginBlockedResponse();
                }
                else
                {
                    // If we already have a session...
                    if (userProfile.CurrentAgent != null && userProfile.CurrentAgent.AgentOnline)
                    {
                        // Force a refresh for this due to Commit below
						UUID userID = userProfile.ID;
                        m_userManager.PurgeUserFromCaches(userID);
                        userProfile = m_userManager.GetUserProfile(userID);
                        // on an error, return the former error we returned before recovery was supported.
                        if (userProfile == null) 
                            return logResponse.CreateAlreadyLoggedInResponse();

                        //TODO: The following statements can cause trouble:
                        //      If agentOnline could not turn from true back to false normally
                        //      because of some problem, for instance, the crashment of server or client,
                        //      the user cannot log in any longer.
                        userProfile.CurrentAgent.AgentOnline = false;
                        userProfile.CurrentAgent.LogoutTime = Util.UnixTimeSinceEpoch();

                        m_userManager.CommitAgent(ref userProfile);

                        // try to tell the region that their user is dead.
                        LogOffUser(userProfile, " XMLRPC You were logged off because you logged in from another location");

                        // Don't reject the login. We've already cleaned it up, above.
                        m_log.InfoFormat(
                            "[LOGIN END]: XMLRPC Reset user {0} {1} that we believe is already logged in",
                            firstname, lastname);
                        // return logResponse.CreateAlreadyLoggedInResponse();
                    }

                    // Otherwise...
                    // Create a new agent session

                    m_userManager.ResetAttachments(userProfile.ID);


                    CreateAgent(userProfile, request);

                    // We need to commit the agent right here, even though the userProfile info is not complete
                    // at this point. There is another commit further down.
                    // This is for the new sessionID to be stored so that the region can check it for session authentication. 
                    // CustomiseResponse->PrepareLoginToRegion
                    CommitAgent(ref userProfile);

                    try
                    {
                        UUID agentID = userProfile.ID;
                        InventoryData inventData = null;

                        try
                        {
                            inventData = GetInventorySkeleton(agentID);
                        }
                        catch (Exception e)
                        {
                            m_log.ErrorFormat(
                                "[LOGIN END]: Error retrieving inventory skeleton of agent {0} - {1}",
                                agentID, e);

                            return logResponse.CreateLoginInventoryFailedResponse();
                        }

                        if (inventData != null)
                        {
                            ArrayList AgentInventoryArray = inventData.InventoryArray;

                            Hashtable InventoryRootHash = new Hashtable();
                            InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
                            ArrayList InventoryRoot = new ArrayList();
                            InventoryRoot.Add(InventoryRootHash);
                            userProfile.RootInventoryFolderID = inventData.RootFolderID;

                            logResponse.InventoryRoot = InventoryRoot;
                            logResponse.InventorySkeleton = AgentInventoryArray;
                        }

                        // Inventory Library Section
                        Hashtable InventoryLibRootHash = new Hashtable();
                        InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
                        ArrayList InventoryLibRoot = new ArrayList();
                        InventoryLibRoot.Add(InventoryLibRootHash);

                        logResponse.InventoryLibRoot = InventoryLibRoot;
                        logResponse.InventoryLibraryOwner = GetLibraryOwner();
                        logResponse.InventoryLibrary = GetInventoryLibrary();

                        logResponse.CircuitCode = Util.RandomClass.Next();
                        logResponse.Lastname = userProfile.SurName;
                        logResponse.Firstname = userProfile.FirstName;
                        logResponse.AgentID = agentID;
                        logResponse.SessionID = userProfile.CurrentAgent.SessionID;
                        logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID;
                        logResponse.Message = GetMessage();
                        logResponse.MapServerURI = m_MapServerURI;
                        logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID));
                        logResponse.StartLocation = startLocationRequest;
//                        m_log.WarnFormat("[LOGIN END]: >>> Login response for {0} SSID={1}", logResponse.AgentID, logResponse.SecureSessionID);

                        if (CustomiseResponse(logResponse, userProfile, startLocationRequest, clientVersion))
                        {
                            userProfile.LastLogin = userProfile.CurrentAgent.LoginTime;
                            CommitAgent(ref userProfile);

                            // If we reach this point, then the login has successfully logged onto the grid
                            if (StatsManager.UserStats != null)
                                StatsManager.UserStats.AddSuccessfulLogin();

                            m_log.DebugFormat(
                                "[LOGIN END]: XMLRPC Authentication of user {0} {1} successful.  Sending response to client.",
                                firstname, lastname);

                            return logResponse.ToXmlRpcResponse();
                        }
                        else
                        {
                            m_log.ErrorFormat("[LOGIN END]: XMLRPC informing user {0} {1} that login failed due to an unavailable region", firstname, lastname);
                            return logResponse.CreateDeadRegionResponse();
                        }
                    }
                    catch (Exception e)
                    {
                        m_log.Error("[LOGIN END]: XMLRPC Login failed, " + e);
                        m_log.Error(e.StackTrace);
                    }
                }

                m_log.Info("[LOGIN END]: XMLRPC Login failed.  Sending back blank XMLRPC response");
                return response;
            }
            finally
            {
                if (loginUsername != null)
                {
                    lock (_loginsProcessing)
                    {
                        _loginsProcessing.Remove(loginUsername);
                    }
                }
            }
        }
Exemplo n.º 8
0
        protected bool PrepareLoginToREURI(Regex reURI, LoginResponse response, UserProfileData theUser, string startLocationRequest, string StartLocationType, string desc, string clientVersion)
        {
			string region;
			RegionInfo regionInfo = null;
            Match uriMatch = reURI.Match(startLocationRequest);
            if (uriMatch == null)
            {
                m_log.InfoFormat("[LOGIN]: Got {0} {1}, but can't process it", desc, startLocationRequest);
				return false;
            }

            region = uriMatch.Groups["region"].ToString();
            regionInfo = RequestClosestRegion(region);
            if (regionInfo == null)
            {
                m_log.InfoFormat("[LOGIN]: Got {0} {1}, can't locate region {2}", desc, startLocationRequest, region);
				return false;
            }
            theUser.CurrentAgent.Position = new Vector3(float.Parse(uriMatch.Groups["x"].Value),
                                                        float.Parse(uriMatch.Groups["y"].Value), float.Parse(uriMatch.Groups["z"].Value));
            response.LookAt = "[r0,r1,r0]";
            // can be: last, home, safe, url
			response.StartLocation = StartLocationType;
			return PrepareLoginToRegion(regionInfo, theUser, response, clientVersion);
		}
Exemplo n.º 9
0
        /// <summary>
        /// Add active gestures of the user to the login response.
        /// </summary>
        /// <param name="response">
        /// A <see cref="LoginResponse"/>
        /// </param>
        /// <param name="theUser">
        /// A <see cref="UserProfileData"/>
        /// </param>
        protected void AddActiveGestures(LoginResponse response, UserProfileData theUser)
        {
            IInventoryProviderSelector inventorySelect = ProviderRegistry.Instance.Get<IInventoryProviderSelector>();
            IInventoryStorage inventory = inventorySelect.GetProvider(theUser.ID);

            List<InventoryItemBase> gestures = null;
            try
            {
                gestures = inventory.GetActiveGestureItems(theUser.ID);
            }
            catch (Exception e)
            {
                m_log.Debug("[LOGIN]: Unable to retrieve active gestures from inventory server. Reason: " + e.Message);
            }
            //m_log.DebugFormat("[LOGIN]: AddActiveGestures, found {0}", gestures == null ? 0 : gestures.Count);
            ArrayList list = new ArrayList();
            if (gestures != null)
            {
                foreach (InventoryItemBase gesture in gestures)
                {
                    Hashtable item = new Hashtable();
                    item["item_id"] = gesture.ID.ToString();
                    item["asset_id"] = gesture.AssetID.ToString();
                    list.Add(item);
                }
            }
            response.ActiveGestures = list;
        }
Exemplo n.º 10
0
 protected abstract bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response, string clientVersion);
Exemplo n.º 11
0
        /// <summary>
        /// Prepare a login to the given region.  This involves both telling the region to expect a connection
        /// and appropriately customising the response to the user.
        /// </summary>
        /// <param name="sim"></param>
        /// <param name="user"></param>
        /// <param name="response"></param>
        /// <returns>true if the region was successfully contacted, false otherwise</returns>
        protected override bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response, string clientVersion)
        {
            IPEndPoint endPoint = regionInfo.ExternalEndPoint;
            response.SimAddress = endPoint.Address.ToString();
            response.SimPort = (uint)endPoint.Port;
            response.RegionX = regionInfo.RegionLocX;
            response.RegionY = regionInfo.RegionLocY;

            string capsPath = CapsUtil.GetRandomCapsObjectPath();
            string capsSeedPath = CapsUtil.GetCapsSeedPath(capsPath);

            // Don't use the following!  It Fails for logging into any region not on the same port as the http server!
            // Kept here so it doesn't happen again!
            // response.SeedCapability = regionInfo.ServerURI + capsSeedPath;

            string seedcap = "http://" + regionInfo.ExternalHostName + ":" + m_serversInfo.HttpListenerPort + capsSeedPath;

            response.SeedCapability = seedcap;

            // Notify the target of an incoming user
            m_log.InfoFormat(
                "[LOGIN]: Telling {0} @ {1},{2} to prepare for client connection",
                regionInfo.RegionName, response.RegionX, response.RegionY);

            // Update agent with target sim
            user.CurrentAgent.Region = regionInfo.RegionID;
            user.CurrentAgent.Handle = regionInfo.RegionHandle;

            AgentCircuitData agent = new AgentCircuitData();
            agent.AgentID = user.ID;
            agent.FirstName = user.FirstName;
            agent.LastName = user.SurName;
            agent.SessionID = user.CurrentAgent.SessionID;
            agent.SecureSessionID = user.CurrentAgent.SecureSessionID;
            agent.CircuitCode = Convert.ToUInt32(response.CircuitCode);
            agent.BaseFolder = UUID.Zero;
            agent.InventoryFolder = UUID.Zero;
            agent.startpos = user.CurrentAgent.Position;
            agent.CapsPath = capsPath;
            agent.Appearance = m_userManager.GetUserAppearance(user.ID);
            agent.ClientVersion = clientVersion;

            if (agent.Appearance == null)
            {
                m_log.WarnFormat("[INTER]: Appearance not found for {0} {1}. Creating default.", agent.FirstName, agent.LastName);
                agent.Appearance = new AvatarAppearance(agent.AgentID);
            }

            if (m_regionsConnector.RegionLoginsEnabled)
            {
                string reason;
                bool success = m_regionsConnector.NewUserConnection(regionInfo.RegionHandle, agent, true, out reason);
                if (!success)
                {
                    response.ErrorReason = "key";
                    response.ErrorMessage = reason;
                }
                return success;
                // return m_regionsConnector.NewUserConnection(regionInfo.RegionHandle, agent, out reason);
            }

            return false;
        }
Exemplo n.º 12
0
        /// <summary>
        /// Not really informing the region. Just filling out the response fields related to the region. 
        /// </summary>
        /// <param name="sim"></param>
        /// <param name="user"></param>
        /// <param name="response"></param>
        /// <returns>true if the region was successfully contacted, false otherwise</returns>
        protected override bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint remoteClient)
        {
            IPEndPoint endPoint = regionInfo.ExternalEndPoint;
            response.SimAddress = endPoint.Address.ToString();
            response.SimPort = (uint)endPoint.Port;
            response.RegionX = regionInfo.RegionLocX;
            response.RegionY = regionInfo.RegionLocY;
            response.SimHttpPort = regionInfo.HttpPort;

            string capsPath = CapsUtil.GetRandomCapsObjectPath();
            string capsSeedPath = CapsUtil.GetCapsSeedPath(capsPath);

            // Don't use the following!  It Fails for logging into any region not on the same port as the http server!
            // Kept here so it doesn't happen again!
            // response.SeedCapability = regionInfo.ServerURI + capsSeedPath;

            string seedcap = "http://";

            if (m_serversInfo.HttpUsesSSL)
            {
                // For NAT
                string host = NetworkUtil.GetHostFor(remoteClient.Address, m_serversInfo.HttpSSLCN);

                seedcap = "https://" + host + ":" + m_serversInfo.httpSSLPort + capsSeedPath;
            }
            else
            {
                // For NAT
                string host = NetworkUtil.GetHostFor(remoteClient.Address, regionInfo.ExternalHostName);

                seedcap = "http://" + host + ":" + m_serversInfo.HttpListenerPort + capsSeedPath;
            }

            response.SeedCapability = seedcap;

            // Notify the target of an incoming user
            m_log.InfoFormat(
                "[LOGIN]: Telling {0} @ {1},{2} ({3}) to prepare for client connection",
                regionInfo.RegionName, response.RegionX, response.RegionY, regionInfo.ServerURI);

            // Update agent with target sim
            user.CurrentAgent.Region = regionInfo.RegionID;
            user.CurrentAgent.Handle = regionInfo.RegionHandle;

            return true;
        }
Exemplo n.º 13
0
        XmlRpcResponse LoginHandler(XmlRpcRequest request, Uri requestUrl)
        {
            XmlRpcResponse response = new XmlRpcResponse();
            Hashtable requestData = (Hashtable)request.Params[0];
            IPEndPoint remoteClient = null;
            if (request.Params.Count > 1)
                remoteClient = request.Params[1] as IPEndPoint;

            UserProfileData userProfile;
            LoginResponse logResponse = new LoginResponse();

            UUID sessionID;
            IsXmlRpcLogin(requestUrl, out sessionID);
            m_log.Info("[CABLE BEACH XMLRPC]: XML-RPC Received login request message with sessionID " + sessionID);

            string startLocationRequest = "last";
            if (requestData.Contains("start"))
                startLocationRequest = (requestData["start"] as string) ?? "last";

            string clientVersion = "Unknown";
            if (requestData.Contains("version"))
                clientVersion = (requestData["version"] as string) ?? "Unknown";

            if (TryAuthenticateXmlRpcLogin(sessionID, out userProfile))
            {
                try
                {
                    UUID agentID = userProfile.ID;
                    LoginService.InventoryData skeleton = null;

                    try { skeleton = CableBeachState.LoginService.GetInventorySkeleton(agentID); }
                    catch (Exception e)
                    {
                        m_log.ErrorFormat("[CABLE BEACH XMLRPC]: Error retrieving inventory skeleton of agent {0} - {1}",
                            agentID, e);

                        // Let's not panic
                        if (!CableBeachState.LoginService.AllowLoginWithoutInventory())
                            return logResponse.CreateLoginInventoryFailedResponse();
                    }

                    #region Inventory Skeletons

                    if (skeleton != null)
                    {
                        ArrayList AgentInventoryArray = skeleton.InventoryArray;

                        Hashtable InventoryRootHash = new Hashtable();
                        InventoryRootHash["folder_id"] = skeleton.RootFolderID.ToString();
                        ArrayList InventoryRoot = new ArrayList();
                        InventoryRoot.Add(InventoryRootHash);

                        logResponse.InventoryRoot = InventoryRoot;
                        logResponse.InventorySkeleton = AgentInventoryArray;
                    }

                    // Inventory Library Section
                    Hashtable InventoryLibRootHash = new Hashtable();
                    InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
                    ArrayList InventoryLibRoot = new ArrayList();
                    InventoryLibRoot.Add(InventoryLibRootHash);

                    logResponse.InventoryLibRoot = InventoryLibRoot;
                    logResponse.InventoryLibraryOwner = CableBeachState.LoginService.GetLibraryOwner();
                    logResponse.InventoryLibrary = CableBeachState.LoginService.GetInventoryLibrary();

                    logResponse.CircuitCode = Util.RandomClass.Next();
                    logResponse.Lastname = userProfile.SurName;
                    logResponse.Firstname = userProfile.FirstName;
                    logResponse.AgentID = agentID;
                    logResponse.SessionID = userProfile.CurrentAgent.SessionID;
                    logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID;
                    logResponse.Message = CableBeachState.LoginService.GetMessage();
                    logResponse.BuddList = CableBeachState.LoginService.ConvertFriendListItem(CableBeachState.LoginService.UserManager.GetUserFriendList(agentID));
                    logResponse.StartLocation = startLocationRequest;

                    #endregion Inventory Skeletons

                    if (CableBeachState.LoginService.CustomiseResponse(logResponse, userProfile, startLocationRequest, remoteClient))
                    {
                        userProfile.LastLogin = userProfile.CurrentAgent.LoginTime;
                        CableBeachState.LoginService.CommitAgent(ref userProfile);

                        // If we reach this point, then the login has successfully logged onto the grid
                        if (StatsManager.UserStats != null)
                            StatsManager.UserStats.AddSuccessfulLogin();

                        m_log.DebugFormat("[CABLE BEACH XMLRPC]: Authentication of user {0} {1} successful. Sending response to client",
                            userProfile.FirstName, userProfile.FirstName);

                        return logResponse.ToXmlRpcResponse();
                    }
                    else
                    {
                        m_log.ErrorFormat("[CABLE BEACH XMLRPC]: Informing user {0} {1} that login failed due to an unavailable region",
                            userProfile.FirstName, userProfile.FirstName);

                        return logResponse.CreateDeadRegionResponse();
                    }
                }
                catch (Exception e)
                {
                    m_log.Error("[CABLE BEACH XMLRPC]: Login failed, returning a blank response. Error: " + e);
                    return response;
                }
            }
            else
            {
                m_log.Warn("[CABLE BEACH XMLRPC]: Authentication failed using sessionID " + sessionID + ", there are " +
                    CableBeachState.PendingLogins.Count + " valid pending logins");
                return logResponse.CreateLoginFailedResponse();
            }
        }