diff options
Diffstat (limited to '')
6 files changed, 149 insertions, 3 deletions
diff --git a/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs index 89d64ca..04a0c5e 100644 --- a/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs +++ b/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs | |||
@@ -329,6 +329,63 @@ namespace OpenSim.Services.Connectors | |||
329 | return pinfo; | 329 | return pinfo; |
330 | } | 330 | } |
331 | 331 | ||
332 | public PresenceInfo GetAgentByUser(UUID userID) | ||
333 | { | ||
334 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
335 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
336 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
337 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
338 | sendData["METHOD"] = "getagentbyuser"; | ||
339 | |||
340 | sendData["UserID"] = userID.ToString(); | ||
341 | |||
342 | string reply = string.Empty; | ||
343 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
344 | string uri = m_ServerURI + "/presence"; | ||
345 | // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); | ||
346 | try | ||
347 | { | ||
348 | reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
349 | uri, | ||
350 | reqString, | ||
351 | m_Auth); | ||
352 | if (reply == null || (reply != null && reply == string.Empty)) | ||
353 | { | ||
354 | m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgentByUser received null or empty reply"); | ||
355 | return null; | ||
356 | } | ||
357 | } | ||
358 | catch (Exception e) | ||
359 | { | ||
360 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); | ||
361 | return null; | ||
362 | } | ||
363 | |||
364 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
365 | PresenceInfo pinfo = null; | ||
366 | |||
367 | if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) | ||
368 | { | ||
369 | if (replyData["result"] is Dictionary<string, object>) | ||
370 | { | ||
371 | pinfo = new PresenceInfo((Dictionary<string, object>)replyData["result"]); | ||
372 | } | ||
373 | else | ||
374 | { | ||
375 | if (replyData["result"].ToString() == "null") | ||
376 | return null; | ||
377 | |||
378 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Invalid reply (result not dictionary) received from presence server when querying for userID {0}", userID.ToString()); | ||
379 | } | ||
380 | } | ||
381 | else | ||
382 | { | ||
383 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Invalid reply received from presence server when querying for userID {0}", userID.ToString()); | ||
384 | } | ||
385 | |||
386 | return pinfo; | ||
387 | } | ||
388 | |||
332 | public PresenceInfo[] GetAgents(string[] userIDs) | 389 | public PresenceInfo[] GetAgents(string[] userIDs) |
333 | { | 390 | { |
334 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | 391 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index 08efefb..2a34379 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs | |||
@@ -222,6 +222,18 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
222 | return ResponseToPresenceInfo(sessionResponse); | 222 | return ResponseToPresenceInfo(sessionResponse); |
223 | } | 223 | } |
224 | 224 | ||
225 | public PresenceInfo GetAgentByUser(UUID userID) | ||
226 | { | ||
227 | OSDMap userResponse = GetUserData(userID); | ||
228 | if (userResponse == null) | ||
229 | { | ||
230 | m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}: {1}",userID.ToString(),userResponse["Message"].AsString()); | ||
231 | return null; | ||
232 | } | ||
233 | |||
234 | return ResponseToPresenceInfo(userResponse); | ||
235 | } | ||
236 | |||
225 | public PresenceInfo[] GetAgents(string[] userIDs) | 237 | public PresenceInfo[] GetAgents(string[] userIDs) |
226 | { | 238 | { |
227 | List<PresenceInfo> presences = new List<PresenceInfo>(); | 239 | List<PresenceInfo> presences = new List<PresenceInfo>(); |
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 5c6abd2..24979be 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs | |||
@@ -391,13 +391,39 @@ namespace OpenSim.Services.HypergridService | |||
391 | 391 | ||
392 | if(!m_allowDuplicatePresences) | 392 | if(!m_allowDuplicatePresences) |
393 | { | 393 | { |
394 | //// TODO - Should also check Presence.UserID if RegionID == UUID.Zero, they are a ghost. Maybe. | ||
395 | //// NOTE - this is a person hypergridding in, or returning home, or just logging in and it's duplicating effort in OpenSim/Services/LLLoginService/LLLoginService.cs. | ||
394 | if(guinfo != null && guinfo.Online && guinfo.LastRegionID != UUID.Zero) | 396 | if(guinfo != null && guinfo.Online && guinfo.LastRegionID != UUID.Zero) |
395 | { | 397 | { |
396 | if(SendAgentGodKillToRegion(UUID.Zero, agentID, guinfo)) | 398 | // Also check Presence.UserID if RegionID == UUID.Zero, they are a ghost. |
399 | // Ghosting might be caused by failure to call PresenceService.LogoutAgent() on logout / crash / failed login. | ||
400 | // Might also need to double check if they are out hypergridding. | ||
401 | |||
402 | bool success = false; | ||
403 | if (m_PresenceService != null) | ||
404 | { | ||
405 | PresenceInfo pi = m_PresenceService.GetAgentByUser(account.PrincipalID); | ||
406 | if (null != pi) | ||
407 | { | ||
408 | Dictionary<string, object> pid = pi.ToKeyValuePairs(); | ||
409 | if ((pid["RegionID"].ToString() == UUID.Zero.ToString()) && (0 != String.Compare(pid["SessionID"].ToString(), aCircuit.SessionID.ToString()))) | ||
410 | { | ||
411 | m_log.WarnFormat("[GATEKEEPER SERVICE]: Exorcising ghost avatar {0}, session {1}, new session {2}.", pid["UserID"], pid["SessionID"], aCircuit.SessionID); | ||
412 | m_log.WarnFormat("[GATEKEEPER SERVICE]: NOT REALLY."); | ||
413 | //// Don't do this until after more checking. | ||
414 | //// success = m_PresenceService.LogoutAgent(new UUID(pid["SessionID"].ToString())); | ||
415 | //// if (success) | ||
416 | //// m_log.WarnFormat("[GATEKEEPER SERVICE]: Ghost avatar exorcised {0}, session {1}, new session {2}.", pid["UserID"], pid["SessionID"], aCircuit.SessionID); | ||
417 | //// else | ||
418 | //// m_log.ErrorFormat("[GATEKEEPER SERVICE]: Ghost avatar not exorcised {0}, session {1}, new session {2}!", pid["UserID"], pid["SessionID"], aCircuit.SessionID); | ||
419 | } | ||
420 | } | ||
421 | } | ||
422 | if ((!success) && SendAgentGodKillToRegion(UUID.Zero, agentID, guinfo)) | ||
397 | { | 423 | { |
398 | if(account != null) | 424 | if(account != null) |
399 | m_log.InfoFormat( | 425 | m_log.InfoFormat( |
400 | "[GATEKEEPER SERVICE]: Login failed for {0} {1}, reason: already logged in", | 426 | "[GATEKEEPER SERVICE]: Login failed for {0} {1}, reason: already logged in. This may be bogus if a ghost avatar was exorcised above.", |
401 | account.FirstName, account.LastName); | 427 | account.FirstName, account.LastName); |
402 | reason = "You appear to be already logged in on the destination grid " + | 428 | reason = "You appear to be already logged in on the destination grid " + |
403 | "Please wait a a minute or two and retry. " + | 429 | "Please wait a a minute or two and retry. " + |
diff --git a/OpenSim/Services/Interfaces/IPresenceService.cs b/OpenSim/Services/Interfaces/IPresenceService.cs index 90f9842..4843759 100644 --- a/OpenSim/Services/Interfaces/IPresenceService.cs +++ b/OpenSim/Services/Interfaces/IPresenceService.cs | |||
@@ -36,6 +36,7 @@ namespace OpenSim.Services.Interfaces | |||
36 | { | 36 | { |
37 | public string UserID; | 37 | public string UserID; |
38 | public UUID RegionID; | 38 | public UUID RegionID; |
39 | public UUID SessionID; | ||
39 | 40 | ||
40 | public PresenceInfo() | 41 | public PresenceInfo() |
41 | { | 42 | { |
@@ -47,6 +48,8 @@ namespace OpenSim.Services.Interfaces | |||
47 | UserID = kvp["UserID"].ToString(); | 48 | UserID = kvp["UserID"].ToString(); |
48 | if (kvp.ContainsKey("RegionID")) | 49 | if (kvp.ContainsKey("RegionID")) |
49 | UUID.TryParse(kvp["RegionID"].ToString(), out RegionID); | 50 | UUID.TryParse(kvp["RegionID"].ToString(), out RegionID); |
51 | if (kvp.ContainsKey("SessionID")) | ||
52 | UUID.TryParse(kvp["SessionID"].ToString(), out SessionID); | ||
50 | } | 53 | } |
51 | 54 | ||
52 | public Dictionary<string, object> ToKeyValuePairs() | 55 | public Dictionary<string, object> ToKeyValuePairs() |
@@ -54,6 +57,7 @@ namespace OpenSim.Services.Interfaces | |||
54 | Dictionary<string, object> result = new Dictionary<string, object>(); | 57 | Dictionary<string, object> result = new Dictionary<string, object>(); |
55 | result["UserID"] = UserID; | 58 | result["UserID"] = UserID; |
56 | result["RegionID"] = RegionID.ToString(); | 59 | result["RegionID"] = RegionID.ToString(); |
60 | result["SessionID"] = SessionID.ToString(); | ||
57 | 61 | ||
58 | return result; | 62 | return result; |
59 | } | 63 | } |
@@ -100,6 +104,13 @@ namespace OpenSim.Services.Interfaces | |||
100 | PresenceInfo GetAgent(UUID sessionID); | 104 | PresenceInfo GetAgent(UUID sessionID); |
101 | 105 | ||
102 | /// <summary> | 106 | /// <summary> |
107 | /// Get session information for a given session ID. | ||
108 | /// </summary> | ||
109 | /// <returns></returns> | ||
110 | /// <param name='sessionID'></param> | ||
111 | PresenceInfo GetAgentByUser(UUID userID); | ||
112 | |||
113 | /// <summary> | ||
103 | /// Get session information for a collection of users. | 114 | /// Get session information for a collection of users. |
104 | /// </summary> | 115 | /// </summary> |
105 | /// <returns>Session information for the users.</returns> | 116 | /// <returns>Session information for the users.</returns> |
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 53a3c2f..cad0988 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs | |||
@@ -390,7 +390,30 @@ namespace OpenSim.Services.LLLoginService | |||
390 | { | 390 | { |
391 | if(guinfo != null && guinfo.Online && guinfo.LastRegionID != UUID.Zero) | 391 | if(guinfo != null && guinfo.Online && guinfo.LastRegionID != UUID.Zero) |
392 | { | 392 | { |
393 | if(SendAgentGodKillToRegion(scopeID, account.PrincipalID, guinfo)) | 393 | // Also check Presence.UserID if RegionID == UUID.Zero, they are a ghost. |
394 | // Ghosting might be caused by failure to call PresenceService.LogoutAgent() on logout / crash / failed login. | ||
395 | // Might also need to double check if they are out hypergridding. | ||
396 | |||
397 | success = false; | ||
398 | if (m_PresenceService != null) | ||
399 | { | ||
400 | PresenceInfo pi = m_PresenceService.GetAgentByUser(account.PrincipalID); | ||
401 | if (null != pi) | ||
402 | { | ||
403 | Dictionary<string, object> pid = pi.ToKeyValuePairs(); | ||
404 | if (pid["RegionID"].ToString() == UUID.Zero.ToString()) | ||
405 | { | ||
406 | m_log.WarnFormat("[LLOGIN SERVICE]: Exorcising ghost avatar {0} {1}, session {2}, new session {3}.", firstName, lastName, pid["SessionID"], session); | ||
407 | success = m_PresenceService.LogoutAgent(new UUID(pid["SessionID"].ToString())); | ||
408 | if (success) | ||
409 | m_log.WarnFormat("[LLOGIN SERVICE]: Ghost avatar exorcised {0} {1}, session {2}, new session {3}.", firstName, lastName, pid["SessionID"], session); | ||
410 | else | ||
411 | m_log.ErrorFormat("[LLOGIN SERVICE]: Ghost avatar not exorcised {0} {1}, session {2}, new session {3}!", firstName, lastName, pid["SessionID"], session); | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | |||
416 | if ((!success) && SendAgentGodKillToRegion(scopeID, account.PrincipalID, guinfo)) | ||
394 | { | 417 | { |
395 | m_log.InfoFormat( | 418 | m_log.InfoFormat( |
396 | "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: already logged in", | 419 | "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: already logged in", |
diff --git a/OpenSim/Services/PresenceService/PresenceService.cs b/OpenSim/Services/PresenceService/PresenceService.cs index 0392409..1059b2b 100644 --- a/OpenSim/Services/PresenceService/PresenceService.cs +++ b/OpenSim/Services/PresenceService/PresenceService.cs | |||
@@ -151,6 +151,22 @@ namespace OpenSim.Services.PresenceService | |||
151 | 151 | ||
152 | ret.UserID = data.UserID; | 152 | ret.UserID = data.UserID; |
153 | ret.RegionID = data.RegionID; | 153 | ret.RegionID = data.RegionID; |
154 | ret.SessionID = data.SessionID; | ||
155 | |||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | public PresenceInfo GetAgentByUser(UUID userID) | ||
160 | { | ||
161 | PresenceInfo ret = new PresenceInfo(); | ||
162 | |||
163 | PresenceData data = m_Database.GetByUser(userID); | ||
164 | if (data == null) | ||
165 | return null; | ||
166 | |||
167 | ret.UserID = data.UserID; | ||
168 | ret.RegionID = data.RegionID; | ||
169 | ret.SessionID = data.SessionID; | ||
154 | 170 | ||
155 | return ret; | 171 | return ret; |
156 | } | 172 | } |
@@ -169,6 +185,7 @@ namespace OpenSim.Services.PresenceService | |||
169 | 185 | ||
170 | ret.UserID = d.UserID; | 186 | ret.UserID = d.UserID; |
171 | ret.RegionID = d.RegionID; | 187 | ret.RegionID = d.RegionID; |
188 | ret.SessionID = d.SessionID; | ||
172 | 189 | ||
173 | info.Add(ret); | 190 | info.Add(ret); |
174 | } | 191 | } |