From 33f511ee4b5b4e1f8fe4fbb47d3b5b51e1d0104a Mon Sep 17 00:00:00 2001 From: lbsa71 Date: Thu, 12 Mar 2009 10:50:59 +0000 Subject: * Another stab at refactoring up the CustomiseResponse function. Two fixes: * Sometimes, null is a valid return value to indicate 'none found'. doh. * Sometimes, the Grid server does not send simURI - this you need to reconstruct yourself. Euw. (I believe) this solves mantis issue #3287 --- OpenSim/Framework/Communications/LoginService.cs | 156 +++++++++++++++++++++-- 1 file changed, 147 insertions(+), 9 deletions(-) (limited to 'OpenSim/Framework/Communications/LoginService.cs') diff --git a/OpenSim/Framework/Communications/LoginService.cs b/OpenSim/Framework/Communications/LoginService.cs index 36d7280..278ea43 100644 --- a/OpenSim/Framework/Communications/LoginService.cs +++ b/OpenSim/Framework/Communications/LoginService.cs @@ -78,15 +78,6 @@ namespace OpenSim.Framework.Communications } /// - /// Customises the login response and fills in missing values. This method also tells the login region to - /// expect a client connection. - /// - /// The existing response - /// The user profile - /// true on success, false if the region was not successfully told to expect a user connection - public abstract bool CustomiseResponse(LoginResponse response, UserProfileData theUser, string startLocationRequest); - - /// /// If the user is already logged in, try to notify the region that the user they've got is dead. /// /// @@ -872,5 +863,152 @@ namespace OpenSim.Framework.Communications m_log.InfoFormat("[LOGIN]: Login with web_login_key {0}", web_login_key); } } + + /// + /// Customises the login response and fills in missing values. This method also tells the login region to + /// expect a client connection. + /// + /// The existing response + /// The user profile + /// The requested start location + /// true on success, false if the region was not successfully told to expect a user connection + public bool CustomiseResponse(LoginResponse response, UserProfileData theUser, string startLocationRequest) + { + // 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 (startLocationRequest == "home") + { + regionInfo = homeInfo; + theUser.CurrentAgent.Position = theUser.HomeLocation; + response.LookAt = "[r" + theUser.HomeLookAt.X.ToString() + ",r" + theUser.HomeLookAt.Y.ToString() + ",r" + theUser.HomeLookAt.Z.ToString() + "]"; + } + else if (startLocationRequest == "last") + { + UUID lastRegion = theUser.CurrentAgent.Region; + regionInfo = GetRegionInfo(lastRegion); + response.LookAt = "[r" + theUser.CurrentAgent.LookAt.X.ToString() + ",r" + theUser.CurrentAgent.LookAt.Y.ToString() + ",r" + theUser.CurrentAgent.LookAt.Z.ToString() + "]"; + } + else + { + Regex reURI = new Regex(@"^uri:(?[^&]+)&(?\d+)&(?\d+)&(?\d+)$"); + Match uriMatch = reURI.Match(startLocationRequest); + if (uriMatch == null) + { + m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, but can't process it", startLocationRequest); + } + else + { + string region = uriMatch.Groups["region"].ToString(); + regionInfo = RequestClosestRegion(region); + if (regionInfo == null) + { + m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, can't locate region {1}", startLocationRequest, region); + } + else + { + 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 = "url"; + } + + if ((regionInfo != null) && (PrepareLoginToRegion(regionInfo, theUser, response))) + { + 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); + + // Send him to default region instead + 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; + } + + // Customise the response + //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}]}}", + // (SimInfo.regionLocX * Constants.RegionSize), + // (SimInfo.regionLocY*Constants.RegionSize), + // theUser.HomeLocation.X, theUser.HomeLocation.Y, theUser.HomeLocation.Z, + // theUser.HomeLookAt.X, theUser.HomeLookAt.Y, theUser.HomeLookAt.Z); + theUser.CurrentAgent.Position = new Vector3(128, 128, 0); + response.StartLocation = "safe"; + + return PrepareLoginToRegion(regionInfo, theUser, response); + } + + protected abstract RegionInfo RequestClosestRegion(string region); + protected abstract RegionInfo GetRegionInfo(ulong homeRegionHandle); + protected abstract RegionInfo GetRegionInfo(UUID homeRegionId); + protected abstract void AddActiveGestures(LoginResponse response, UserProfileData theUser); + protected abstract bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response); } } -- cgit v1.1