From 52a4c4d82f9c5b808e6c61fd51c1c70e42865565 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Fri, 12 Sep 2008 20:12:03 +0000 Subject: * Check in first part of http://opensimulator.org/mantis/view.php?id=2073 * This patch aims to introduce look at direction persistence between logins. It won't be active until the second part of the patch is committed in about two weeks time. At this point, region servers that haven't upgraded past this revision may run into problems * This checkin upgrades the user database. As always, we recommend you have backups in case something goes wrong. * Many thanks to tyre for this patch. --- OpenSim/Data/MySQL/MySQLManager.cs | 9 +- .../Communications/CommunicationsManager.cs | 14 +- OpenSim/Framework/Communications/IUserService.cs | 13 +- OpenSim/Framework/Communications/LoginService.cs | 35 +-- .../Framework/Communications/UserManagerBase.cs | 196 ++++++++-------- OpenSim/Framework/Constants.cs | 48 +++- OpenSim/Framework/UserAgentData.cs | 98 ++++---- OpenSim/Framework/Util.cs | 2 + OpenSim/Grid/UserServer/UserLoginService.cs | 239 +++++++++---------- .../Communications/Local/LocalLoginService.cs | 257 ++++++++++----------- .../Region/Communications/OGS1/OGS1UserServices.cs | 35 ++- .../Modules/InterGrid/OpenGridProtocolModule.cs | 3 - .../Scenes/SceneCommunicationService.cs | 12 +- OpenSim/Region/Environment/Scenes/ScenePresence.cs | 5 + 14 files changed, 515 insertions(+), 451 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLManager.cs b/OpenSim/Data/MySQL/MySQLManager.cs index 6048f93..5f830bb 100644 --- a/OpenSim/Data/MySQL/MySQLManager.cs +++ b/OpenSim/Data/MySQL/MySQLManager.cs @@ -512,6 +512,8 @@ namespace OpenSim.Data.MySQL Vector3 tmp_v; Vector3.TryParse((string) reader["currentPos"], out tmp_v); retval.Position = tmp_v; + Vector3.TryParse((string)reader["currentLookAt"], out tmp_v); + retval.LookAt = tmp_v; } else { @@ -1095,8 +1097,8 @@ namespace OpenSim.Data.MySQL { string sql = String.Empty; sql += "REPLACE INTO "; - sql += "agents (UUID, sessionID, secureSessionID, agentIP, agentPort, agentOnline, loginTime, logoutTime, currentRegion, currentHandle, currentPos) VALUES "; - sql += "(?UUID, ?sessionID, ?secureSessionID, ?agentIP, ?agentPort, ?agentOnline, ?loginTime, ?logoutTime, ?currentRegion, ?currentHandle, ?currentPos);"; + sql += "agents (UUID, sessionID, secureSessionID, agentIP, agentPort, agentOnline, loginTime, logoutTime, currentRegion, currentHandle, currentPos, currentLookAt) VALUES "; + sql += "(?UUID, ?sessionID, ?secureSessionID, ?agentIP, ?agentPort, ?agentOnline, ?loginTime, ?logoutTime, ?currentRegion, ?currentHandle, ?currentPos, ?currentLookAt);"; Dictionary parameters = new Dictionary(); parameters["?UUID"] = agentdata.ProfileID.ToString(); @@ -1109,7 +1111,8 @@ namespace OpenSim.Data.MySQL parameters["?logoutTime"] = agentdata.LogoutTime.ToString(); parameters["?currentRegion"] = agentdata.Region.ToString(); parameters["?currentHandle"] = agentdata.Handle.ToString(); - parameters["?currentPos"] = "<" + ((int)agentdata.Position.X).ToString() + "," + ((int)agentdata.Position.Y).ToString() + "," + ((int)agentdata.Position.Z).ToString() + ">"; + parameters["?currentPos"] = "<" + (agentdata.Position.X).ToString() + "," + (agentdata.Position.Y).ToString() + "," + (agentdata.Position.Z).ToString() + ">"; + parameters["?currentLookAt"] = "<" + (agentdata.LookAt.X).ToString() + "," + (agentdata.LookAt.Y).ToString() + "," + (agentdata.LookAt.Z).ToString() + ">"; bool returnval = false; diff --git a/OpenSim/Framework/Communications/CommunicationsManager.cs b/OpenSim/Framework/Communications/CommunicationsManager.cs index e6413e8..969bdd8 100644 --- a/OpenSim/Framework/Communications/CommunicationsManager.cs +++ b/OpenSim/Framework/Communications/CommunicationsManager.cs @@ -276,13 +276,25 @@ namespace OpenSim.Framework.Communications /// /// /// + /// + /// + public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat) + { + m_userService.LogOffUser(userid, regionid, regionhandle, position, lookat); + } + + /// + /// Logs off a user and does the appropriate communications (deprecated as of 2008-08-27) + /// + /// + /// + /// /// /// /// public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz) { m_userService.LogOffUser(userid, regionid, regionhandle, posx, posy, posz); - } /// diff --git a/OpenSim/Framework/Communications/IUserService.cs b/OpenSim/Framework/Communications/IUserService.cs index 07ea437..7e3c77b 100644 --- a/OpenSim/Framework/Communications/IUserService.cs +++ b/OpenSim/Framework/Communications/IUserService.cs @@ -106,7 +106,18 @@ namespace OpenSim.Framework.Communications /// Logs off a user on the user server /// /// UUID of the user - /// UUID of the Region + /// UUID of the Region + /// regionhandle + /// final position + /// final lookat + void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat); + + /// + /// Logs off a user on the user server (deprecated as of 2008-08-27) + /// + /// UUID of the user + /// UUID of the Region + /// regionhandle /// final position x /// final position y /// final position z diff --git a/OpenSim/Framework/Communications/LoginService.cs b/OpenSim/Framework/Communications/LoginService.cs index 7cdbf6c..26ae3c6 100644 --- a/OpenSim/Framework/Communications/LoginService.cs +++ b/OpenSim/Framework/Communications/LoginService.cs @@ -258,30 +258,19 @@ namespace OpenSim.Framework.Communications InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; ArrayList InventoryLibRoot = new ArrayList(); InventoryLibRoot.Add(InventoryLibRootHash); - logResponse.InventoryLibRoot = InventoryLibRoot; + logResponse.InventoryLibRoot = InventoryLibRoot; logResponse.InventoryLibraryOwner = GetLibraryOwner(); - logResponse.InventoryRoot = InventoryRoot; logResponse.InventorySkeleton = AgentInventoryArray; logResponse.InventoryLibrary = GetInventoryLibrary(); - // Circuit Code - uint circode = (uint) (Util.RandomClass.Next()); - + logResponse.CircuitCode = (Int32)Util.RandomClass.Next(); logResponse.Lastname = userProfile.SurName; logResponse.Firstname = userProfile.FirstName; logResponse.AgentID = agentID.ToString(); logResponse.SessionID = userProfile.CurrentAgent.SessionID.ToString(); logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID.ToString(); - - logResponse.CircuitCode = (Int32) circode; - //logResponse.RegionX = 0; //overwritten - //logResponse.RegionY = 0; //overwritten - logResponse.Home = "!!null temporary value {home}!!"; // Overwritten - //logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n"; - //logResponse.SimAddress = "127.0.0.1"; //overwritten - //logResponse.SimPort = 0; //overwritten logResponse.Message = GetMessage(); logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID)); logResponse.StartLocation = startLocationRequest; @@ -322,6 +311,11 @@ namespace OpenSim.Framework.Communications } } + /// + /// Called when we receive the client's initial LLSD login_to_simulator request message + /// + /// The LLSD request + /// The response to send public LLSD LLSDLoginMethod(LLSD request) { // Temporary fix @@ -432,30 +426,19 @@ namespace OpenSim.Framework.Communications InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; ArrayList InventoryLibRoot = new ArrayList(); InventoryLibRoot.Add(InventoryLibRootHash); - logResponse.InventoryLibRoot = InventoryLibRoot; + logResponse.InventoryLibRoot = InventoryLibRoot; logResponse.InventoryLibraryOwner = GetLibraryOwner(); - logResponse.InventoryRoot = InventoryRoot; logResponse.InventorySkeleton = AgentInventoryArray; logResponse.InventoryLibrary = GetInventoryLibrary(); - // Circuit Code - uint circode = (uint)(Util.RandomClass.Next()); - + logResponse.CircuitCode = (Int32)Util.RandomClass.Next(); logResponse.Lastname = userProfile.SurName; logResponse.Firstname = userProfile.FirstName; logResponse.AgentID = agentID.ToString(); logResponse.SessionID = userProfile.CurrentAgent.SessionID.ToString(); logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID.ToString(); - - logResponse.CircuitCode = (Int32)circode; - //logResponse.RegionX = 0; //overwritten - //logResponse.RegionY = 0; //overwritten - logResponse.Home = "!!null temporary value {home}!!"; // Overwritten - //logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n"; - //logResponse.SimAddress = "127.0.0.1"; //overwritten - //logResponse.SimPort = 0; //overwritten logResponse.Message = GetMessage(); logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID)); logResponse.StartLocation = startLocationRequest; diff --git a/OpenSim/Framework/Communications/UserManagerBase.cs b/OpenSim/Framework/Communications/UserManagerBase.cs index b6564bf..75c4dc1 100644 --- a/OpenSim/Framework/Communications/UserManagerBase.cs +++ b/OpenSim/Framework/Communications/UserManagerBase.cs @@ -388,84 +388,115 @@ namespace OpenSim.Framework.Communications // Profile UUID agent.ProfileID = profile.ID; - // Current position (from Home) - agent.Handle = profile.HomeRegion; - agent.Position = profile.HomeLocation; - - // If user specified additional start, use that - if (requestData.ContainsKey("start")) + // Current location/position/alignment + if (profile.CurrentAgent != null) { - string startLoc = ((string)requestData["start"]).Trim(); - if (("last" == startLoc) && (profile.CurrentAgent != null)) - { - if ((profile.CurrentAgent.Position.X > 0) - && (profile.CurrentAgent.Position.Y > 0) - && (profile.CurrentAgent.Position.Z > 0) - ) - { - // TODO: Right now, currentRegion has not been used in GridServer for requesting region. - // TODO: It is only using currentHandle. - agent.Region = profile.CurrentAgent.Region; - agent.Handle = profile.CurrentAgent.Handle; - agent.Position = profile.CurrentAgent.Position; - } - } - -// if (!(startLoc == "last" || startLoc == "home")) -// { -// // Format: uri:Ahern&162&213&34 -// try -// { -// string[] parts = startLoc.Remove(0, 4).Split('&'); -// //string region = parts[0]; -// -// //////////////////////////////////////////////////// -// //SimProfile SimInfo = new SimProfile(); -// //SimInfo = SimInfo.LoadFromGrid(theUser.currentAgent.currentHandle, _config.GridServerURL, _config.GridSendKey, _config.GridRecvKey); -// } -// catch (Exception) -// { -// } -// } + agent.Region = profile.CurrentAgent.Region; + agent.Handle = profile.CurrentAgent.Handle; + agent.Position = profile.CurrentAgent.Position; + agent.LookAt = profile.CurrentAgent.LookAt; + } + else + { + agent.Region = profile.HomeRegionID; + agent.Handle = profile.HomeRegion; + agent.Position = profile.HomeLocation; + agent.LookAt = profile.HomeLookAt; } // What time did the user login? agent.LoginTime = Util.UnixTimeSinceEpoch(); agent.LogoutTime = 0; - // Current location - agent.InitialRegion = UUID.Zero; // Fill in later - agent.Region = UUID.Zero; // Fill in later + profile.CurrentAgent = agent; + } + + public void CreateAgent(UserProfileData profile, LLSD request) + { + UserAgentData agent = new UserAgentData(); + + // User connection + agent.AgentOnline = true; + + //if (request.Params.Count > 1) + //{ + // IPEndPoint RemoteIPEndPoint = (IPEndPoint)request.Params[1]; + // agent.AgentIP = RemoteIPEndPoint.Address.ToString(); + // agent.AgentPort = (uint)RemoteIPEndPoint.Port; + //} + + // Generate sessions + RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider(); + byte[] randDataS = new byte[16]; + byte[] randDataSS = new byte[16]; + rand.GetBytes(randDataS); + rand.GetBytes(randDataSS); + + agent.SecureSessionID = new UUID(randDataSS, 0); + agent.SessionID = new UUID(randDataS, 0); + + // Profile UUID + agent.ProfileID = profile.ID; + + // Current location/position/alignment + if (profile.CurrentAgent != null) + { + agent.Region = profile.CurrentAgent.Region; + agent.Handle = profile.CurrentAgent.Handle; + agent.Position = profile.CurrentAgent.Position; + agent.LookAt = profile.CurrentAgent.LookAt; + } + else + { + agent.Region = profile.HomeRegionID; + agent.Handle = profile.HomeRegion; + agent.Position = profile.HomeLocation; + agent.LookAt = profile.HomeLookAt; + } + + // What time did the user login? + agent.LoginTime = Util.UnixTimeSinceEpoch(); + agent.LogoutTime = 0; profile.CurrentAgent = agent; } /// + /// Saves a target agent to the database + /// + /// The users profile + /// Successful? + public bool CommitAgent(ref UserProfileData profile) + { + // TODO: how is this function different from setUserProfile? -> Add AddUserAgent() here and commit both tables "users" and "agents" + // TODO: what is the logic should be? + bool ret = false; + ret = AddUserAgent(profile.CurrentAgent); + ret = ret & UpdateUserProfile(profile); + return ret; + } + + /// /// Process a user logoff from OpenSim. /// /// /// /// - /// - /// - /// - public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz) + /// + /// + public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat) { if (StatsManager.UserStats != null) StatsManager.UserStats.AddLogout(); - UserProfileData userProfile; - UserAgentData userAgent; - Vector3 currentPos = new Vector3(posx, posy, posz); - - userProfile = GetUserProfile(userid); + UserProfileData userProfile = GetUserProfile(userid); if (userProfile != null) { // This line needs to be in side the above if statement or the UserServer will crash on some logouts. - m_log.Info("[LOGOUT]: " + userProfile.FirstName + " " + userProfile.SurName + " from " + regionhandle + "(" + posx + "," + posy + "," + posz + ")"); + m_log.Info("[LOGOUT]: " + userProfile.FirstName + " " + userProfile.SurName + " from " + regionhandle + "(" + position.X + "," + position.Y + "," + position.Z + ")"); - userAgent = userProfile.CurrentAgent; + UserAgentData userAgent = userProfile.CurrentAgent; if (userAgent != null) { userAgent.AgentOnline = false; @@ -475,10 +506,11 @@ namespace OpenSim.Framework.Communications { userAgent.Region = regionid; } - userAgent.Handle = regionhandle; - userAgent.Position = currentPos; - userProfile.CurrentAgent = userAgent; + userAgent.Position = position; + userAgent.LookAt = lookat; + //userProfile.CurrentAgent = userAgent; + userProfile.LastLogin = userAgent.LogoutTime; CommitAgent(ref userProfile); } @@ -494,54 +526,18 @@ namespace OpenSim.Framework.Communications } } - public void CreateAgent(UserProfileData profile, LLSD request) - { - UserAgentData agent = new UserAgentData(); - - // User connection - agent.AgentOnline = true; - - // Generate sessions - RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider(); - byte[] randDataS = new byte[16]; - byte[] randDataSS = new byte[16]; - rand.GetBytes(randDataS); - rand.GetBytes(randDataSS); - - agent.SecureSessionID = new UUID(randDataSS, 0); - agent.SessionID = new UUID(randDataS, 0); - - // Profile UUID - agent.ProfileID = profile.ID; - - // Current position (from Home) - agent.Handle = profile.HomeRegion; - agent.Position = profile.HomeLocation; - - // What time did the user login? - agent.LoginTime = Util.UnixTimeSinceEpoch(); - agent.LogoutTime = 0; - - // Current location - agent.InitialRegion = UUID.Zero; // Fill in later - agent.Region = UUID.Zero; // Fill in later - - profile.CurrentAgent = agent; - } - /// - /// Saves a target agent to the database + /// Process a user logoff from OpenSim (deprecated as of 2008-08-27) /// - /// The users profile - /// Successful? - public bool CommitAgent(ref UserProfileData profile) + /// + /// + /// + /// + /// + /// + public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz) { - // TODO: how is this function different from setUserProfile? -> Add AddUserAgent() here and commit both tables "users" and "agents" - // TODO: what is the logic should be? - bool ret = false; - ret = AddUserAgent(profile.CurrentAgent); - ret = ret & UpdateUserProfile(profile); - return ret; + LogOffUser(userid, regionid, regionhandle, new Vector3(posx, posy, posz), new Vector3()); } #endregion diff --git a/OpenSim/Framework/Constants.cs b/OpenSim/Framework/Constants.cs index 316d2a3..61eb35e 100644 --- a/OpenSim/Framework/Constants.cs +++ b/OpenSim/Framework/Constants.cs @@ -24,6 +24,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; namespace OpenSim.Framework { @@ -40,5 +41,50 @@ namespace OpenSim.Framework EstateBans = 20, EstateManagers = 24 } + + [Flags]public enum TeleportFlags : uint + { + /// No flags set, or teleport failed + Default = 0, + /// Set when newbie leaves help island for first time + SetHomeToTarget = 1 << 0, + /// + SetLastToTarget = 1 << 1, + /// Via Lure + ViaLure = 1 << 2, + /// Via Landmark + ViaLandmark = 1 << 3, + /// Via Location + ViaLocation = 1 << 4, + /// Via Home + ViaHome = 1 << 5, + /// Via Telehub + ViaTelehub = 1 << 6, + /// Via Login + ViaLogin = 1 << 7, + /// Linden Summoned + ViaGodlikeLure = 1 << 8, + /// Linden Forced me + Godlike = 1 << 9, + /// + NineOneOne = 1 << 10, + /// Agent Teleported Home via Script + DisableCancel = 1 << 11, + /// + ViaRegionID = 1 << 12, + /// + IsFlying = 1 << 13, + /// + ResetHome = 1 << 14, + /// forced to new location for example when avatar is banned or ejected + ForceRedirect = 1 << 15, + /// Teleport Finished via a Lure + FinishedViaLure = 1 << 26, + /// Finished, Sim Changed + FinishedViaNewSim = 1 << 28, + /// Finished, Same Sim + FinishedViaSameSim = 1 << 29 + } + } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/UserAgentData.cs b/OpenSim/Framework/UserAgentData.cs index 03a65c5..506a5e0 100644 --- a/OpenSim/Framework/UserAgentData.cs +++ b/OpenSim/Framework/UserAgentData.cs @@ -36,34 +36,35 @@ namespace OpenSim.Framework public class UserAgentData { /// - /// The IP address of the user + /// The UUID of the users avatar (not the agent!) /// - private string agentIP = String.Empty; + private UUID UUID; /// - /// Is the user online? + /// The session ID for the user (also the agent ID) /// - private bool agentOnline; + private UUID sessionID; /// - /// The port of the user + /// The "secure" session ID for the user /// - private uint agentPort; + /// Not very secure. Dont rely on it for anything more than Linden Lab does. + private UUID secureSessionID; /// - /// Region handle of the current region the user is in + /// The IP address of the user /// - private ulong currentHandle; + private string agentIP = String.Empty; /// - /// The position of the user within the region + /// The port of the user /// - private Vector3 currentPos; + private uint agentPort; /// - /// Current region the user is logged into + /// Is the user online? /// - private UUID currentRegion; + private bool agentOnline; /// /// A unix timestamp from when the user logged in @@ -76,25 +77,29 @@ namespace OpenSim.Framework private int logoutTime; /// - /// The region the user logged into initially + /// Region ID the user is logged into /// private UUID regionID; /// - /// The "secure" session ID for the user + /// Region handle of the current region the user is in /// - /// Not very secure. Dont rely on it for anything more than Linden Lab does. - private UUID secureSessionID; + private ulong regionHandle; /// - /// The session ID for the user (also the agent ID) + /// The position of the user within the region /// - private UUID sessionID; + private Vector3 currentPos; /// - /// The UUID of the users avatar (not the agent!) + /// Current direction the user is looking at /// - private UUID UUID; + private Vector3 currentLookAt = Vector3.Zero; + + /// + /// The region the user logged into initially + /// + private UUID originRegionID; public virtual UUID ProfileID { @@ -102,6 +107,18 @@ namespace OpenSim.Framework set { UUID = value; } } + public virtual UUID SessionID + { + get { return sessionID; } + set { sessionID = value; } + } + + public virtual UUID SecureSessionID + { + get { return secureSessionID; } + set { secureSessionID = value; } + } + public virtual string AgentIP { get { return agentIP; } @@ -120,24 +137,6 @@ namespace OpenSim.Framework set { agentOnline = value; } } - public virtual UUID SessionID - { - get { return sessionID; } - set { sessionID = value; } - } - - public virtual UUID SecureSessionID - { - get { return secureSessionID; } - set { secureSessionID = value; } - } - - public virtual UUID InitialRegion - { - get { return regionID; } - set { regionID = value; } - } - public virtual int LoginTime { get { return loginTime; } @@ -152,14 +151,14 @@ namespace OpenSim.Framework public virtual UUID Region { - get { return currentRegion; } - set { currentRegion = value; } + get { return regionID; } + set { regionID = value; } } public virtual ulong Handle { - get { return currentHandle; } - set { currentHandle = value; } + get { return regionHandle; } + set { regionHandle = value; } } public virtual Vector3 Position @@ -168,6 +167,7 @@ namespace OpenSim.Framework set { currentPos = value; } } +/* 2008-08-28-tyre: Not really useful public virtual float PositionX { get { return currentPos.X; } @@ -185,5 +185,19 @@ namespace OpenSim.Framework get { return currentPos.Z; } set { currentPos.Z = value; } } +*/ + + public virtual Vector3 LookAt + { + get { return currentLookAt; } + set { currentLookAt = value; } + } + + public virtual UUID InitialRegion + { + get { return originRegionID; } + set { originRegionID = value; } + } + } } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index d289978..333ab81 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -678,6 +678,7 @@ namespace OpenSim.Framework } } +/* 2008-08-28-tyre: Obsolete (see LocalLoginService UserLoginService) public static string[] ParseStartLocationRequest(string startLocationRequest) { string[] returnstring = new string[4]; @@ -715,6 +716,7 @@ namespace OpenSim.Framework } return returnstring; } +*/ public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args) { diff --git a/OpenSim/Grid/UserServer/UserLoginService.cs b/OpenSim/Grid/UserServer/UserLoginService.cs index 07b29bd..8ab9af1 100644 --- a/OpenSim/Grid/UserServer/UserLoginService.cs +++ b/OpenSim/Grid/UserServer/UserLoginService.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; +using System.Text.RegularExpressions; using OpenMetaverse; using log4net; using Nwc.XmlRpc; @@ -127,94 +128,25 @@ namespace OpenSim.Grid.UserServer /// /// The existing response /// The user profile - /// Destination of the user - public override bool CustomiseResponse(LoginResponse response, UserProfileData theUser, - string startLocationRequest) + /// The requested start location + public override bool CustomiseResponse(LoginResponse response, UserProfileData theUser, string startLocationRequest) { - RegionProfileData SimInfo; - RegionProfileData HomeInfo; - int start_x = -1; - int start_y = -1; - int start_z = -1; - + // HomeLocation + RegionProfileData homeInfo = null; // use the homeRegionID if it is stored already. If not, use the regionHandle as before if (theUser.HomeRegionID != UUID.Zero) - { - HomeInfo = - RegionProfileData.RequestSimProfileData( - theUser.HomeRegionID, m_config.GridServerURL, - m_config.GridSendKey, m_config.GridRecvKey); - } + homeInfo = RegionProfileData.RequestSimProfileData(theUser.HomeRegionID, + m_config.GridServerURL, m_config.GridSendKey, m_config.GridRecvKey); else - { - HomeInfo = - RegionProfileData.RequestSimProfileData( - theUser.HomeRegion, m_config.GridServerURL, - m_config.GridSendKey, m_config.GridRecvKey); - } - - if (startLocationRequest == "last") - { - SimInfo = - RegionProfileData.RequestSimProfileData( - theUser.CurrentAgent.Handle, m_config.GridServerURL, - m_config.GridSendKey, m_config.GridRecvKey); - } - else if (startLocationRequest == "home") - { - SimInfo = HomeInfo; - } - else - { - string[] startLocationRequestParsed = Util.ParseStartLocationRequest(startLocationRequest); - m_log.Info("[DEBUGLOGINPARSE]: 1:" + startLocationRequestParsed[0] + ", 2:" + - startLocationRequestParsed[1] + ", 3:" + startLocationRequestParsed[2] + ", 4:" + - startLocationRequestParsed[3]); - if (startLocationRequestParsed[0] == "last") - { - SimInfo = - RegionProfileData.RequestSimProfileData( - theUser.CurrentAgent.Handle, m_config.GridServerURL, - m_config.GridSendKey, m_config.GridRecvKey); - } - else - { - m_log.Info("[LOGIN]: Looking up Sim: " + startLocationRequestParsed[0]); - SimInfo = - RegionProfileData.RequestSimProfileData( - startLocationRequestParsed[0], m_config.GridServerURL, - m_config.GridSendKey, m_config.GridRecvKey); - - if (SimInfo == null) - { - m_log.Info("[LOGIN]: Didn't find region with a close name match sending to home location"); - SimInfo = HomeInfo; - } - else - { - start_x = Convert.ToInt32(startLocationRequestParsed[1]); - start_y = Convert.ToInt32(startLocationRequestParsed[2]); - start_z = Convert.ToInt32(startLocationRequestParsed[3]); - - if (start_x >= 0 && start_y >= 0 && start_z >= 0) - { - Vector3 tmp_v = new Vector3(start_x, start_y, start_z); - theUser.CurrentAgent.Position = tmp_v; - } - } - } - } - - // Customise the response - //CFK: This is redundant and the next message should always appear. - //CFK: m_log.Info("[LOGIN]: Home Location"); - if (HomeInfo != null) + homeInfo = RegionProfileData.RequestSimProfileData(theUser.HomeRegion, + m_config.GridServerURL, m_config.GridSendKey, m_config.GridRecvKey); + 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), + (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); } @@ -236,42 +168,85 @@ namespace OpenSim.Grid.UserServer regionX, regionY); } - if (!PrepareLoginToRegion(SimInfo, theUser, response)) + // StartLocation + RegionProfileData regionInfo = null; + if (startLocationRequest == "home") { - // Send him to default region instead - // Load information from the gridserver - ulong defaultHandle = (((ulong) m_config.DefaultX * Constants.RegionSize) << 32) | - ((ulong) m_config.DefaultY * Constants.RegionSize); - - if (defaultHandle == SimInfo.regionHandle) + 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") + { + regionInfo = RegionProfileData.RequestSimProfileData(theUser.CurrentAgent.Region, + m_config.GridServerURL, m_config.GridSendKey, m_config.GridRecvKey); + 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.ErrorFormat("[LOGIN]: Not trying the default region since this is the same as the selected region"); - return false; + m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, but can't process it", startLocationRequest); } + else + { + string region = uriMatch.Groups["region"].ToString(); + regionInfo = RegionProfileData.RequestSimProfileData(region, + m_config.GridServerURL, m_config.GridSendKey, m_config.GridRecvKey); + 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["x"].Value)); + } + } + response.LookAt = "[r0,r1,r0]"; + // can be: last, home, safe, url + response.StartLocation = "url"; + } - m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead"); + if ((regionInfo != null) && (PrepareLoginToRegion(regionInfo, theUser, response))) + { + return true; + } - SimInfo = RegionProfileData.RequestSimProfileData(defaultHandle, m_config.GridServerURL, m_config.GridSendKey, m_config.GridRecvKey); + // StartLocation not available, send him to a nearby region instead + //regionInfo = RegionProfileData.RequestSimProfileData("", m_config.GridServerURL, m_config.GridSendKey, m_config.GridRecvKey); + //m_log.InfoFormat("[LOGIN]: StartLocation not available sending to region {0}", regionInfo.regionName); - // 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); + // Send him to default region instead + // Load information from the gridserver + ulong defaultHandle = (((ulong) m_config.DefaultX * Constants.RegionSize) << 32) | + ((ulong) m_config.DefaultY * Constants.RegionSize); - if (!PrepareLoginToRegion(SimInfo, theUser, response)) - { - response.CreateDeadRegionResponse(); - return false; - } + 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; } - return true; - } + m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead"); + regionInfo = RegionProfileData.RequestSimProfileData(defaultHandle, m_config.GridServerURL, m_config.GridSendKey, m_config.GridRecvKey); + // 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); + } + /// /// 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. @@ -280,47 +255,46 @@ namespace OpenSim.Grid.UserServer /// /// /// true if the region was successfully contacted, false otherwise - private bool PrepareLoginToRegion(RegionProfileData sim, UserProfileData user, LoginResponse response) + private bool PrepareLoginToRegion(RegionProfileData regionInfo, UserProfileData user, LoginResponse response) { try - { - response.SimAddress = Util.GetHostFromURL(sim.serverURI).ToString(); - response.SimPort = uint.Parse(sim.serverURI.Split(new char[] {'/', ':'})[4]); - response.RegionX = sim.regionLocX; - response.RegionY = sim.regionLocY; + { + response.SimAddress = Util.GetHostFromURL(regionInfo.serverURI).ToString(); + response.SimPort = uint.Parse(regionInfo.serverURI.Split(new char[] { '/', ':' })[4]); + response.RegionX = regionInfo.regionLocX; + response.RegionY = regionInfo.regionLocY; //Not sure if the + "/CAPS/" should in fact be +"CAPS/" depending if there is already a / as part of httpServerURI string capsPath = Util.GetRandomCapsPath(); - response.SeedCapability = sim.httpServerURI + "CAPS/" + capsPath + "0000/"; + response.SeedCapability = regionInfo.httpServerURI + "CAPS/" + capsPath + "0000/"; // Notify the target of an incoming user m_log.InfoFormat( "[LOGIN]: Telling {0} @ {1},{2} ({3}) to prepare for client connection", - sim.regionName, sim.regionLocX, sim.regionLocY, sim.serverURI); - + regionInfo.regionName, response.RegionX, response.RegionY, regionInfo.httpServerURI); // Update agent with target sim - user.CurrentAgent.Region = sim.UUID; - user.CurrentAgent.Handle = sim.regionHandle; - + user.CurrentAgent.Region = regionInfo.UUID; + user.CurrentAgent.Handle = regionInfo.regionHandle; // Prepare notification - Hashtable SimParams = new Hashtable(); - SimParams["session_id"] = user.CurrentAgent.SessionID.ToString(); - SimParams["secure_session_id"] = user.CurrentAgent.SecureSessionID.ToString(); - SimParams["firstname"] = user.FirstName; - SimParams["lastname"] = user.SurName; - SimParams["agent_id"] = user.ID.ToString(); - SimParams["circuit_code"] = (Int32) Convert.ToUInt32(response.CircuitCode); - SimParams["startpos_x"] = user.CurrentAgent.Position.X.ToString(); - SimParams["startpos_y"] = user.CurrentAgent.Position.Y.ToString(); - SimParams["startpos_z"] = user.CurrentAgent.Position.Z.ToString(); - SimParams["regionhandle"] = user.CurrentAgent.Handle.ToString(); - SimParams["caps_path"] = capsPath; + 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; + ArrayList SendParams = new ArrayList(); - SendParams.Add(SimParams); + SendParams.Add(loginParams); // Send XmlRpcRequest GridReq = new XmlRpcRequest("expect_user", SendParams); - XmlRpcResponse GridResp = GridReq.Send(sim.httpServerURI, 30000); + XmlRpcResponse GridResp = GridReq.Send(regionInfo.httpServerURI, 6000); if (!GridResp.IsFault) { @@ -337,7 +311,6 @@ namespace OpenSim.Grid.UserServer } } } - if (responseSuccess) { handlerUserLoggedInAtLocation = OnUserLoggedInAtLocation; diff --git a/OpenSim/Region/Communications/Local/LocalLoginService.cs b/OpenSim/Region/Communications/Local/LocalLoginService.cs index 93a1e46..2f7fdb7 100644 --- a/OpenSim/Region/Communications/Local/LocalLoginService.cs +++ b/OpenSim/Region/Communications/Local/LocalLoginService.cs @@ -41,8 +41,7 @@ namespace OpenSim.Region.Communications.Local public class LocalLoginService : LoginService { - private static readonly ILog m_log - = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private CommunicationsLocal m_Parent; @@ -120,167 +119,167 @@ namespace OpenSim.Region.Communications.Local } } - private Regex reURI = new Regex(@"^uri:(?[^&]+)&(?\d+)&(?\d+)&(?\d+)$"); - + /// + /// Customises the login response and fills in missing values. + /// + /// The existing response + /// The user profile + /// The requested start location public override bool CustomiseResponse(LoginResponse response, UserProfileData theUser, string startLocationRequest) { - ulong currentRegion = 0; - - uint locX = 0; - uint locY = 0; - uint locZ = 0; - bool specificStartLocation = false; + // HomeLocation + RegionInfo homeInfo = null; + // use the homeRegionID if it is stored already. If not, use the regionHandle as before + if (theUser.HomeRegionID != UUID.Zero) + homeInfo = m_Parent.GridService.RequestNeighbourInfo(theUser.HomeRegionID); + else + homeInfo = m_Parent.GridService.RequestNeighbourInfo(theUser.HomeRegion); + 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 + { + // 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 = theUser.HomeRegion >> 32; + ulong regionY = theUser.HomeRegion & 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); + } - // get start location - if (startLocationRequest == "last") + // StartLocation + RegionInfo regionInfo = null; + if (startLocationRequest == "home") { - currentRegion = theUser.CurrentAgent.Handle; - locX = (UInt32)theUser.CurrentAgent.Position.X; - locY = (UInt32)theUser.CurrentAgent.Position.Y; - locZ = (UInt32)theUser.CurrentAgent.Position.Z; - response.StartLocation = "last"; - specificStartLocation = true; + 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 == "home") + else if (startLocationRequest == "last") { - currentRegion = theUser.HomeRegion; - response.StartLocation = "home"; + regionInfo = m_Parent.GridService.RequestNeighbourInfo(theUser.CurrentAgent.Region); + response.LookAt = "[r" + theUser.CurrentAgent.LookAt.X.ToString() + ",r" + theUser.CurrentAgent.LookAt.Y.ToString() + ",r" + theUser.CurrentAgent.LookAt.Z.ToString() + "]"; } else { - // use last location as default - currentRegion = theUser.CurrentAgent.Handle; - + Regex reURI = new Regex(@"^uri:(?[^&]+)&(?\d+)&(?\d+)&(?\d+)$"); Match uriMatch = reURI.Match(startLocationRequest); - if (null == uriMatch) + 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 r = m_Parent.GridService.RequestClosestRegion(region); - if (null == r) + regionInfo = m_Parent.GridService.RequestClosestRegion(region); + if (regionInfo == null) { - m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, can't locate region {1}", - startLocationRequest, region); + m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, can't locate region {1}", startLocationRequest, region); } else { - currentRegion = r.RegionHandle; - locX = UInt32.Parse(uriMatch.Groups["x"].ToString()); - locY = UInt32.Parse(uriMatch.Groups["y"].ToString()); - locZ = UInt32.Parse(uriMatch.Groups["z"].ToString()); - // can be: last, home, safe, url - response.StartLocation = "url"; - specificStartLocation = true; + theUser.CurrentAgent.Position = new Vector3(float.Parse(uriMatch.Groups["x"].Value), + float.Parse(uriMatch.Groups["y"].Value), float.Parse(uriMatch.Groups["x"].Value)); } } + response.LookAt = "[r0,r1,r0]"; + // can be: last, home, safe, url + response.StartLocation = "url"; } - RegionInfo homeReg = m_Parent.GridService.RequestNeighbourInfo(theUser.HomeRegion); - RegionInfo reg = m_Parent.GridService.RequestNeighbourInfo(currentRegion); - - if ((homeReg != null) || (reg != null)) + if ((regionInfo != null) && (PrepareLoginToRegion(regionInfo, theUser, response))) { - if (homeReg != null) - { - response.Home = "{'region_handle':[r" + - (homeReg.RegionLocX * Constants.RegionSize).ToString() + ",r" + - (homeReg.RegionLocY * Constants.RegionSize).ToString() + "], " + - "'position':[r" + - theUser.HomeLocation.X.ToString() + ",r" + - theUser.HomeLocation.Y.ToString() + ",r" + - theUser.HomeLocation.Z.ToString() + "], " + - "'look_at':[r" + - theUser.HomeLocation.X.ToString() + ",r" + - theUser.HomeLocation.Y.ToString() + ",r" + - theUser.HomeLocation.Z.ToString() + "]}"; - } - else - { - m_log.Warn("[LOGIN]: Your home region doesn't exist"); - response.Home = "{'region_handle':[r" + - (reg.RegionLocX * Constants.RegionSize).ToString() + ",r" + - (reg.RegionLocY * Constants.RegionSize).ToString() + "], " + - "'position':[r" + - theUser.HomeLocation.X.ToString() + ",r" + - theUser.HomeLocation.Y.ToString() + ",r" + - theUser.HomeLocation.Z.ToString() + "], " + - "'look_at':[r" + - theUser.HomeLocation.X.ToString() + ",r" + - theUser.HomeLocation.Y.ToString() + ",r" + - theUser.HomeLocation.Z.ToString() + "]}"; - } - string capsPath = Util.GetRandomCapsPath(); - response.SimAddress = reg.ExternalEndPoint.Address.ToString(); - response.SimPort = (uint) reg.ExternalEndPoint.Port; - response.RegionX = reg.RegionLocX; - response.RegionY = reg.RegionLocY; - - m_log.DebugFormat( - "[CAPS][LOGIN]: RegionX {0} RegionY {0}", response.RegionX, response.RegionY); - - response.SeedCapability = "http://" + reg.ExternalHostName + ":" + - serversInfo.HttpListenerPort.ToString() + "/CAPS/" + capsPath + "0000/"; - - m_log.DebugFormat( - "[CAPS]: Sending new CAPS seed url {0} to client {1}", - response.SeedCapability, response.AgentID); - - theUser.CurrentAgent.Region = reg.RegionID; - theUser.CurrentAgent.Handle = reg.RegionHandle; - - // LoginResponse.BuddyList buddyList = new LoginResponse.BuddyList(); - - response.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(theUser.ID)); - - Login _login = new Login(); - //copy data to login object - _login.First = response.Firstname; - _login.Last = response.Lastname; - _login.Agent = response.AgentID; - _login.Session = response.SessionID; - _login.SecureSession = response.SecureSessionID; - _login.CircuitCode = (uint) response.CircuitCode; - if (specificStartLocation) - _login.StartPos = new Vector3(locX, locY, locZ); - else - _login.StartPos = new Vector3(128, 128, 128); - _login.CapsPath = capsPath; + return true; + } - m_log.InfoFormat( - "[LOGIN]: Telling region {0} @ {1},{2} ({3}:{4}) to expect user connection", - reg.RegionName, response.RegionX, response.RegionY, response.SimAddress, response.SimPort); + // StartLocation not available, send him to a nearby region instead + // regionInfo = m_Parent.GridService.RequestClosestRegion(""); + //m_log.InfoFormat("[LOGIN]: StartLocation not available sending to region {0}", regionInfo.regionName); - handlerLoginToRegion = OnLoginToRegion; - if (handlerLoginToRegion != null) - { - handlerLoginToRegion(currentRegion, _login); - } - } - else + // Send him to default region instead + ulong defaultHandle = (((ulong)defaultHomeX * Constants.RegionSize) << 32) | + ((ulong)defaultHomeY * Constants.RegionSize); + + if ((regionInfo != null) && (defaultHandle == regionInfo.RegionHandle)) { - m_log.Warn("[LOGIN]: Not found region " + currentRegion); + m_log.ErrorFormat("[LOGIN]: Not trying the default region since this is the same as the selected region"); return false; } - return true; + m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead"); + regionInfo = m_Parent.GridService.RequestNeighbourInfo(defaultHandle); + + // 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); } - private LoginResponse.BuddyList ConvertFriendListItem(List LFL) + /// + /// 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. + /// + /// + /// + /// + /// true if the region was successfully contacted, false otherwise + private bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response) { - LoginResponse.BuddyList buddylistreturn = new LoginResponse.BuddyList(); - foreach (FriendListItem fl in LFL) - { - LoginResponse.BuddyList.BuddyInfo buddyitem = new LoginResponse.BuddyList.BuddyInfo(fl.Friend); - buddyitem.BuddyID = fl.Friend; - buddyitem.BuddyRightsHave = (int)fl.FriendListOwnerPerms; - buddyitem.BuddyRightsGiven = (int)fl.FriendPerms; - buddylistreturn.AddNewBuddy(buddyitem); - } - return buddylistreturn; + response.SimAddress = regionInfo.ExternalEndPoint.Address.ToString(); + response.SimPort = (uint)regionInfo.ExternalEndPoint.Port; + response.RegionX = regionInfo.RegionLocX; + response.RegionY = regionInfo.RegionLocY; + + string capsPath = Util.GetRandomCapsPath(); + response.SeedCapability = regionInfo.ServerURI + "/CAPS/" + capsPath + "0000/"; + + // 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; + // Prepare notification + Login loginParams = new Login(); + loginParams.Session = user.CurrentAgent.SessionID.ToString(); + loginParams.SecureSession = user.CurrentAgent.SecureSessionID.ToString(); + loginParams.First = user.FirstName; + loginParams.Last = user.SurName; + loginParams.Agent = user.ID.ToString(); + loginParams.CircuitCode = Convert.ToUInt32(response.CircuitCode); + loginParams.StartPos = user.CurrentAgent.Position; + loginParams.CapsPath = capsPath; + + handlerLoginToRegion = OnLoginToRegion; + if (handlerLoginToRegion == null) + return false; + + handlerLoginToRegion(user.CurrentAgent.Handle, loginParams); + return true; } // See LoginService diff --git a/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs b/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs index 36a82a8..b8268eb 100644 --- a/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs +++ b/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs @@ -235,19 +235,22 @@ namespace OpenSim.Region.Communications.OGS1 /// Logs off a user on the user server /// /// UUID of the user - /// UUID of the Region - /// final position x - /// final position y - /// final position z - public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz) + /// UUID of the Region + /// regionhandle + /// final position + /// final lookat + public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat) { Hashtable param = new Hashtable(); param["avatar_uuid"] = userid.Guid.ToString(); param["region_uuid"] = regionid.Guid.ToString(); param["region_handle"] = regionhandle.ToString(); - param["region_pos_x"] = posx.ToString(); - param["region_pos_y"] = posy.ToString(); - param["region_pos_z"] = posz.ToString(); + param["region_pos_x"] = position.X.ToString(); + param["region_pos_y"] = position.Y.ToString(); + param["region_pos_z"] = position.Z.ToString(); + param["lookat_x"] = lookat.X.ToString(); + param["lookat_y"] = lookat.Y.ToString(); + param["lookat_z"] = lookat.Z.ToString(); IList parameters = new ArrayList(); parameters.Add(param); @@ -263,6 +266,20 @@ namespace OpenSim.Region.Communications.OGS1 } } + /// + /// Logs off a user on the user server (deprecated as of 2008-08-27) + /// + /// UUID of the user + /// UUID of the Region + /// regionhandle + /// final position x + /// final position y + /// final position z + public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz) + { + LogOffUser(userid, regionid, regionhandle, new Vector3(posx, posy, posz), new Vector3()); + } + public UserProfileData GetUserProfile(string firstName, string lastName) { return GetUserProfile(firstName + " " + lastName); @@ -672,7 +689,7 @@ namespace OpenSim.Region.Communications.OGS1 } } /// - /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner + /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for UUID friendslistowner /// /// The agent that we're retreiving the friends Data. public List GetUserFriendList(UUID friendlistowner) diff --git a/OpenSim/Region/Environment/Modules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/Environment/Modules/InterGrid/OpenGridProtocolModule.cs index 6d06bb5..2604b3f 100644 --- a/OpenSim/Region/Environment/Modules/InterGrid/OpenGridProtocolModule.cs +++ b/OpenSim/Region/Environment/Modules/InterGrid/OpenGridProtocolModule.cs @@ -322,9 +322,6 @@ namespace OpenSim.Region.Environment.Modules.InterGrid useragent.LoginTime=Util.UnixTimeSinceEpoch(); useragent.LogoutTime = 0; useragent.Position=agentData.startpos; - useragent.PositionX=agentData.startpos.X; - useragent.PositionY=agentData.startpos.Y; - useragent.PositionZ=agentData.startpos.Z; useragent.Region=reg.originRegionID; useragent.SecureSessionID=agentData.SecureSessionID; useragent.SessionID = agentData.SessionID; diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index 9ff35c0..887a8da 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -579,7 +579,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// public virtual void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, - Vector3 lookAt, uint flags) + Vector3 lookAt, uint teleportFlags) { bool destRegionUp = false; @@ -604,7 +604,7 @@ namespace OpenSim.Region.Environment.Scenes position.Z = newPosZ; } avatar.ControllingClient.SendTeleportLocationStart(); - avatar.ControllingClient.SendLocalTeleport(position, lookAt, flags); + avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); avatar.Teleport(position); } else @@ -662,7 +662,7 @@ namespace OpenSim.Region.Environment.Scenes m_log.DebugFormat( "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); - avatar.ControllingClient.SendRegionTeleport(reg.RegionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), + avatar.ControllingClient.SendRegionTeleport(reg.RegionHandle, 13, reg.ExternalEndPoint, 4, teleportFlags, capsPath); avatar.MakeChildAgent(); Thread.Sleep(5000); @@ -716,6 +716,12 @@ namespace OpenSim.Region.Environment.Scenes return m_commsProvider.GridService.GetGridSettings(); } + public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat) + { + m_commsProvider.LogOffUser(userid, regionid, regionhandle, position, lookat); + } + + // deprecated as of 2008-08-27 public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz) { m_commsProvider.LogOffUser(userid, regionid, regionhandle, posx, posy, posz); diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 1a4b0c9..abda63e 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -241,6 +241,11 @@ namespace OpenSim.Region.Environment.Scenes get { return m_CameraCenter; } } + public Vector3 Lookat + { + get { return Util.GetNormalizedVector(new Vector3(m_CameraAtAxis.X, m_CameraAtAxis.Y, 0)); } + } + private readonly string m_firstname; public string Firstname -- cgit v1.1