diff --git a/OpenSim/Data/MSSQL/MSSQLUserData.cs b/OpenSim/Data/MSSQL/MSSQLUserData.cs index 0afe47cd8e..518565980a 100644 --- a/OpenSim/Data/MSSQL/MSSQLUserData.cs +++ b/OpenSim/Data/MSSQL/MSSQLUserData.cs @@ -732,6 +732,10 @@ namespace OpenSim.Data.MSSQL } } + override public void LogoutUsers(UUID regionID) + { + } + #endregion #region Other public methods diff --git a/OpenSim/Data/MySQL/MySQLUserData.cs b/OpenSim/Data/MySQL/MySQLUserData.cs index 288ca86815..f203a660f6 100644 --- a/OpenSim/Data/MySQL/MySQLUserData.cs +++ b/OpenSim/Data/MySQL/MySQLUserData.cs @@ -891,5 +891,31 @@ namespace OpenSim.Data.MySQL dbm.Release(); } } + + public override void LogoutUsers(UUID regionID) + { + Dictionary param = new Dictionary(); + param["?regionID"] = regionID.ToString(); + + MySQLSuperManager dbm = GetLockedConnection("LogoutUsers"); + + try + { + dbm.Manager.ExecuteParameterizedSql( + "update " + m_agentsTableName + " SET agentOnline = 0 " + + "where currentRegion = ?regionID", + param); + } + catch (Exception e) + { + dbm.Manager.Reconnect(); + m_log.Error(e.ToString()); + return; + } + finally + { + dbm.Release(); + } + } } } diff --git a/OpenSim/Data/NHibernate/NHibernateUserData.cs b/OpenSim/Data/NHibernate/NHibernateUserData.cs index 5ef48c8784..1bb2b14d73 100644 --- a/OpenSim/Data/NHibernate/NHibernateUserData.cs +++ b/OpenSim/Data/NHibernate/NHibernateUserData.cs @@ -308,6 +308,10 @@ namespace OpenSim.Data.NHibernate { } + public override void LogoutUsers(UUID regionID) + { + } + public override string Name { get { return "NHibernate"; } } diff --git a/OpenSim/Data/SQLite/SQLiteUserData.cs b/OpenSim/Data/SQLite/SQLiteUserData.cs index 369fc51460..b8f1a6830a 100644 --- a/OpenSim/Data/SQLite/SQLiteUserData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserData.cs @@ -1037,5 +1037,9 @@ namespace OpenSim.Data.SQLite override public void ResetAttachments(UUID userID) { } + + override public void LogoutUsers(UUID regionID) + { + } } } diff --git a/OpenSim/Data/UserDataBase.cs b/OpenSim/Data/UserDataBase.cs index a5fc8c874a..c1b320baee 100644 --- a/OpenSim/Data/UserDataBase.cs +++ b/OpenSim/Data/UserDataBase.cs @@ -75,6 +75,8 @@ namespace OpenSim.Data // } public abstract void ResetAttachments(UUID userID); + public abstract void LogoutUsers(UUID regionID); + public abstract string Version {get;} public abstract string Name {get;} public abstract void Initialise(string connect); diff --git a/OpenSim/Framework/Communications/UserManagerBase.cs b/OpenSim/Framework/Communications/UserManagerBase.cs index bc1a593cc0..46b28d73b0 100644 --- a/OpenSim/Framework/Communications/UserManagerBase.cs +++ b/OpenSim/Framework/Communications/UserManagerBase.cs @@ -87,6 +87,14 @@ namespace OpenSim.Framework.Communications return null; } + public void LogoutUsers(UUID regionID) + { + foreach (IUserDataPlugin plugin in _plugins) + { + plugin.LogoutUsers(regionID); + } + } + public void ResetAttachments(UUID userID) { foreach (IUserDataPlugin plugin in _plugins) diff --git a/OpenSim/Framework/IUserData.cs b/OpenSim/Framework/IUserData.cs index 07159cc51a..0936495ff1 100644 --- a/OpenSim/Framework/IUserData.cs +++ b/OpenSim/Framework/IUserData.cs @@ -177,6 +177,8 @@ namespace OpenSim.Framework void UpdateUserAppearance(UUID user, AvatarAppearance appearance); void ResetAttachments(UUID userID); + + void LogoutUsers(UUID regionID); } public class UserDataInitialiser : PluginInitialiserBase diff --git a/OpenSim/Grid/MessagingServer/Main.cs b/OpenSim/Grid/MessagingServer/Main.cs index 84725716f8..5568f73c64 100644 --- a/OpenSim/Grid/MessagingServer/Main.cs +++ b/OpenSim/Grid/MessagingServer/Main.cs @@ -88,6 +88,10 @@ namespace OpenSim.Grid.MessagingServer m_httpServer.AddXmlRPCHandler("login_to_simulator", msgsvc.UserLoggedOn); m_httpServer.AddXmlRPCHandler("logout_of_simulator", msgsvc.UserLoggedOff); m_httpServer.AddXmlRPCHandler("get_presence_info_bulk", msgsvc.GetPresenceInfoBulk); + m_httpServer.AddXmlRPCHandler("region_startup", msgsvc.RegionStartup); + m_httpServer.AddXmlRPCHandler("region_shutdown", msgsvc.RegionShutdown); + m_httpServer.AddXmlRPCHandler("agent_location", msgsvc.AgentLocation); + m_httpServer.AddXmlRPCHandler("agent_leaving", msgsvc.AgentLeaving); m_httpServer.Start(); m_log.Info("[SERVER]: Userserver registration was successful"); diff --git a/OpenSim/Grid/MessagingServer/MessageService.cs b/OpenSim/Grid/MessagingServer/MessageService.cs index 66916b6c1c..a4e54c7918 100644 --- a/OpenSim/Grid/MessagingServer/MessageService.cs +++ b/OpenSim/Grid/MessagingServer/MessageService.cs @@ -558,24 +558,30 @@ namespace OpenSim.Grid.MessagingServer public bool deregisterWithUserServer() { - Hashtable UserParams = new Hashtable(); + Hashtable request = new Hashtable(); + + return SendToUserServer(request, "deregister_messageserver"); + } + + public bool SendToUserServer(Hashtable request, string method) + { // Login / Authentication if (m_cfg.HttpSSL) { - UserParams["uri"] = "https://" + m_cfg.MessageServerIP + ":" + m_cfg.HttpPort; + request["uri"] = "https://" + m_cfg.MessageServerIP + ":" + m_cfg.HttpPort; } else { - UserParams["uri"] = "http://" + m_cfg.MessageServerIP + ":" + m_cfg.HttpPort; + request["uri"] = "http://" + m_cfg.MessageServerIP + ":" + m_cfg.HttpPort; } - UserParams["recvkey"] = m_cfg.UserRecvKey; - UserParams["sendkey"] = m_cfg.UserRecvKey; + request["recvkey"] = m_cfg.UserRecvKey; + request["sendkey"] = m_cfg.UserRecvKey; // Package into an XMLRPC Request ArrayList SendParams = new ArrayList(); - SendParams.Add(UserParams); + SendParams.Add(request); bool success = true; string[] servers = m_cfg.UserServerURL.Split(' '); @@ -585,7 +591,7 @@ namespace OpenSim.Grid.MessagingServer { try { - XmlRpcRequest UserReq = new XmlRpcRequest("deregister_messageserver", SendParams); + XmlRpcRequest UserReq = new XmlRpcRequest(method, SendParams); XmlRpcResponse UserResp = UserReq.Send(m_cfg.UserServerURL, 16000); // Process Response Hashtable UserRespData = (Hashtable)UserResp.Value; @@ -603,5 +609,62 @@ namespace OpenSim.Grid.MessagingServer } #endregion + + public XmlRpcResponse RegionStartup(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable result = new Hashtable(); + result["success"] = "FALSE"; + + if(SendToUserServer(requestData, "region_startup")) + result["success"] = "TRUE"; + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = result; + return response; + } + + public XmlRpcResponse RegionShutdown(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable result = new Hashtable(); + result["success"] = "FALSE"; + + if(SendToUserServer(requestData, "region_shutdown")) + result["success"] = "TRUE"; + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = result; + return response; + } + + public XmlRpcResponse AgentLocation(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable result = new Hashtable(); + result["success"] = "FALSE"; + + if(SendToUserServer(requestData, "agent_location")) + result["success"] = "TRUE"; + + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = result; + return response; + } + + public XmlRpcResponse AgentLeaving(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable result = new Hashtable(); + result["success"] = "FALSE"; + + if(SendToUserServer(requestData, "agent_leaving")) + result["success"] = "TRUE"; + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = result; + return response; + } } } diff --git a/OpenSim/Grid/UserServer/Main.cs b/OpenSim/Grid/UserServer/Main.cs index eb47259ffe..f894ca0672 100644 --- a/OpenSim/Grid/UserServer/Main.cs +++ b/OpenSim/Grid/UserServer/Main.cs @@ -110,6 +110,11 @@ namespace OpenSim.Grid.UserServer m_loginService.OnUserLoggedInAtLocation += NotifyMessageServersUserLoggedInToLocation; m_userManager.OnLogOffUser += NotifyMessageServersUserLoggOff; + m_messagesService.OnAgentLocation += HandleAgentLocation; + m_messagesService.OnAgentLeaving += HandleAgentLeaving; + m_messagesService.OnRegionStartup += HandleRegionStartup; + m_messagesService.OnRegionShutdown += HandleRegionShutdown; + m_log.Info("[REGION]: Starting HTTP process"); m_httpServer = new BaseHttpServer(Cfg.HttpPort); @@ -147,6 +152,10 @@ namespace OpenSim.Grid.UserServer m_httpServer.AddXmlRPCHandler("get_agent_by_uuid", m_userManager.XmlRPCGetAgentMethodUUID); m_httpServer.AddXmlRPCHandler("check_auth_session", m_userManager.XmlRPCCheckAuthSession); m_httpServer.AddXmlRPCHandler("set_login_params", m_loginService.XmlRPCSetLoginParams); + m_httpServer.AddXmlRPCHandler("region_startup", m_messagesService.RegionStartup); + m_httpServer.AddXmlRPCHandler("region_shutdown", m_messagesService.RegionShutdown); + m_httpServer.AddXmlRPCHandler("agent_location", m_messagesService.AgentLocation); + m_httpServer.AddXmlRPCHandler("agent_leaving", m_messagesService.AgentLeaving); // Message Server ---> User Server m_httpServer.AddXmlRPCHandler("register_messageserver", m_messagesService.XmlRPCRegisterMessageServer); m_httpServer.AddXmlRPCHandler("agent_change_region", m_messagesService.XmlRPCUserMovedtoRegion); @@ -442,5 +451,25 @@ namespace OpenSim.Grid.UserServer m_messagesService.TellMessageServersAboutUser(agentID, sessionID, RegionID, regionhandle, positionX, positionY, positionZ, firstname, lastname); } + + public void HandleAgentLocation(UUID agentID, UUID regionID, ulong regionHandle) + { + m_userManager.HandleAgentLocation(agentID, regionID, regionHandle); + } + + public void HandleAgentLeaving(UUID agentID, UUID regionID, ulong regionHandle) + { + m_userManager.HandleAgentLeaving(agentID, regionID, regionHandle); + } + + public void HandleRegionStartup(UUID regionID) + { + m_userManager.HandleRegionStartup(regionID); + } + + public void HandleRegionShutdown(UUID regionID) + { + m_userManager.HandleRegionShutdown(regionID); + } } } diff --git a/OpenSim/Grid/UserServer/MessageServersConnector.cs b/OpenSim/Grid/UserServer/MessageServersConnector.cs index 61f125e207..66596173f0 100644 --- a/OpenSim/Grid/UserServer/MessageServersConnector.cs +++ b/OpenSim/Grid/UserServer/MessageServersConnector.cs @@ -57,7 +57,13 @@ namespace OpenSim.Grid.UserServer public float positionZ; public string firstname; public string lastname; - }; + } + + public delegate void AgentLocationDelegate(UUID agentID, UUID regionID, ulong regionHandle); + public delegate void AgentLeavingDelegate(UUID agentID, UUID regionID, ulong regionHandle); + public delegate void RegionStartupDelegate(UUID regionID); + public delegate void RegionShutdownDelegate(UUID regionID); + public class MessageServersConnector { @@ -70,6 +76,11 @@ namespace OpenSim.Grid.UserServer Thread m_NotifyThread; + public event AgentLocationDelegate OnAgentLocation; + public event AgentLeavingDelegate OnAgentLeaving; + public event RegionStartupDelegate OnRegionStartup; + public event RegionShutdownDelegate OnRegionShutdown; + public MessageServersConnector() { MessageServers = new Dictionary(); @@ -337,5 +348,85 @@ namespace OpenSim.Grid.UserServer } } } + + public XmlRpcResponse RegionStartup(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable result = new Hashtable(); + + UUID regionID; + if (UUID.TryParse((string)requestData["RegionUUID"], out regionID)) + { + if (OnRegionStartup != null) + OnRegionStartup(regionID); + + result["responsestring"] = "TRUE"; + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = result; + return response; + } + + public XmlRpcResponse RegionShutdown(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable result = new Hashtable(); + + UUID regionID; + if (UUID.TryParse((string)requestData["RegionUUID"], out regionID)) + { + if (OnRegionShutdown != null) + OnRegionShutdown(regionID); + + result["responsestring"] = "TRUE"; + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = result; + return response; + } + + public XmlRpcResponse AgentLocation(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable result = new Hashtable(); + + UUID agentID; + UUID regionID; + ulong regionHandle; + if (UUID.TryParse((string)requestData["AgentID"], out agentID) && UUID.TryParse((string)requestData["RegionUUID"], out regionID) && ulong.TryParse((string)requestData["RegionHandle"], out regionHandle)) + { + if (OnAgentLocation != null) + OnAgentLocation(agentID, regionID, regionHandle); + + result["responsestring"] = "TRUE"; + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = result; + return response; + } + + public XmlRpcResponse AgentLeaving(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable result = new Hashtable(); + + UUID agentID; + UUID regionID; + ulong regionHandle; + if (UUID.TryParse((string)requestData["AgentID"], out agentID) && UUID.TryParse((string)requestData["RegionUUID"], out regionID) && ulong.TryParse((string)requestData["RegionHandle"], out regionHandle)) + { + if (OnAgentLeaving != null) + OnAgentLeaving(agentID, regionID, regionHandle); + + result["responsestring"] = "TRUE"; + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = result; + return response; + } } } diff --git a/OpenSim/Grid/UserServer/UserManager.cs b/OpenSim/Grid/UserServer/UserManager.cs index f7e4e3c69b..04510b2b5a 100644 --- a/OpenSim/Grid/UserServer/UserManager.cs +++ b/OpenSim/Grid/UserServer/UserManager.cs @@ -758,5 +758,52 @@ namespace OpenSim.Grid.UserServer { throw new Exception("The method or operation is not implemented."); } + + public void HandleAgentLocation(UUID agentID, UUID regionID, ulong regionHandle) + { + UserProfileData userProfile = GetUserProfile(agentID); + if (userProfile != null) + { + userProfile.CurrentAgent.Region = regionID; + userProfile.CurrentAgent.Handle = regionHandle; + CommitAgent(ref userProfile); + } + } + + public void HandleAgentLeaving(UUID agentID, UUID regionID, ulong regionHandle) + { + UserProfileData userProfile = GetUserProfile(agentID); + if (userProfile != null) + { + if (userProfile.CurrentAgent.Region == regionID) + { + UserAgentData userAgent = userProfile.CurrentAgent; + if (userAgent != null && userAgent.AgentOnline) + { + userAgent.AgentOnline = false; + userAgent.LogoutTime = Util.UnixTimeSinceEpoch(); + if (regionID != UUID.Zero) + { + userAgent.Region = regionID; + } + userAgent.Handle = regionHandle; + userProfile.LastLogin = userAgent.LogoutTime; + + CommitAgent(ref userProfile); + } + } + } + } + + public void HandleRegionStartup(UUID regionID) + { + LogoutUsers(regionID); + } + + public void HandleRegionShutdown(UUID regionID) + { + LogoutUsers(regionID); + } + } } diff --git a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/PresenceModule.cs index aa1db1d8b3..7b358c27f5 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/PresenceModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/PresenceModule.cs @@ -114,10 +114,14 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage public void OnNewClient(IClientAPI client) { client.OnConnectionClosed += OnConnectionClosed; + client.OnLogout += OnConnectionClosed; } public void OnConnectionClosed(IClientAPI client) { + if (!(client.Scene is Scene)) + return; + if (!(m_RootAgents.ContainsKey(client.AgentId))) return; @@ -128,7 +132,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage m_RootAgents.Remove(client.AgentId); - NotifyMessageServerOfAgentLeaving(client.AgentId, scene.RegionInfo.RegionName); + NotifyMessageServerOfAgentLeaving(client.AgentId, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); } public void OnSetRootAgentScene(UUID agentID, Scene scene) @@ -139,13 +143,13 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage return; } m_RootAgents[agentID] = scene; - NotifyMessageServerOfAgentLocation(agentID, scene.RegionInfo.RegionName); + NotifyMessageServerOfAgentLocation(agentID, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); } private void NotifyMessageServerOfStartup(Scene scene) { Hashtable xmlrpcdata = new Hashtable(); - xmlrpcdata["RegionName"] = scene.RegionInfo.RegionName; + xmlrpcdata["RegionUUID"] = scene.RegionInfo.RegionID.ToString(); ArrayList SendParams = new ArrayList(); SendParams.Add(xmlrpcdata); try @@ -154,7 +158,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage XmlRpcResponse resp = UpRequest.Send(scene.CommsManager.NetworkServersInfo.MessagingURL, 5000); Hashtable responseData = (Hashtable)resp.Value; - if ((!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") + if (responseData == null || (!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") { m_log.ErrorFormat("[PRESENCE] Failed to notify message server of region startup for region {0}", scene.RegionInfo.RegionName); } @@ -168,7 +172,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage private void NotifyMessageServerOfShutdown(Scene scene) { Hashtable xmlrpcdata = new Hashtable(); - xmlrpcdata["RegionName"] = scene.RegionInfo.RegionName; + xmlrpcdata["RegionUUID"] = scene.RegionInfo.RegionID.ToString(); ArrayList SendParams = new ArrayList(); SendParams.Add(xmlrpcdata); try @@ -188,11 +192,12 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage } } - private void NotifyMessageServerOfAgentLocation(UUID agentID, string region) + private void NotifyMessageServerOfAgentLocation(UUID agentID, UUID region, ulong regionHandle) { Hashtable xmlrpcdata = new Hashtable(); xmlrpcdata["AgentID"] = agentID.ToString(); - xmlrpcdata["RegionName"] = region; + xmlrpcdata["RegionUUID"] = region.ToString(); + xmlrpcdata["RegionHandle"] = regionHandle.ToString(); ArrayList SendParams = new ArrayList(); SendParams.Add(xmlrpcdata); try @@ -212,11 +217,12 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage } } - private void NotifyMessageServerOfAgentLeaving(UUID agentID, string region) + private void NotifyMessageServerOfAgentLeaving(UUID agentID, UUID region, ulong regionHandle) { Hashtable xmlrpcdata = new Hashtable(); xmlrpcdata["AgentID"] = agentID.ToString(); - xmlrpcdata["RegionName"] = region; + xmlrpcdata["RegionUUID"] = region.ToString(); + xmlrpcdata["RegionHandle"] = regionHandle.ToString(); ArrayList SendParams = new ArrayList(); SendParams.Add(xmlrpcdata); try