Plumb in the presence notifications and region shutdown/restart messages

from the presence module to the message server, through the user server
and on into the database. This should fix the "Already logged in" issue
that grids see after a sim crashes, or a user crashes out of a sim.
Not yet a 100% solution for friends, but getting there.
0.6.1-post-fixes
Melanie Thielker 2008-11-23 05:16:07 +00:00
parent 02fd7751d9
commit cbd0221870
13 changed files with 307 additions and 17 deletions

View File

@ -732,6 +732,10 @@ namespace OpenSim.Data.MSSQL
}
}
override public void LogoutUsers(UUID regionID)
{
}
#endregion
#region Other public methods

View File

@ -891,5 +891,31 @@ namespace OpenSim.Data.MySQL
dbm.Release();
}
}
public override void LogoutUsers(UUID regionID)
{
Dictionary<string, string> param = new Dictionary<string, string>();
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();
}
}
}
}

View File

@ -308,6 +308,10 @@ namespace OpenSim.Data.NHibernate
{
}
public override void LogoutUsers(UUID regionID)
{
}
public override string Name {
get { return "NHibernate"; }
}

View File

@ -1037,5 +1037,9 @@ namespace OpenSim.Data.SQLite
override public void ResetAttachments(UUID userID)
{
}
override public void LogoutUsers(UUID regionID)
{
}
}
}

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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");

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -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<string, MessageServerInfo>();
@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -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