diff options
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
6 files changed, 303 insertions, 155 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index ffe7718..325067c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs | |||
@@ -51,12 +51,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog | |||
51 | m_scene.RegisterModuleInterface<IDialogModule>(this); | 51 | m_scene.RegisterModuleInterface<IDialogModule>(this); |
52 | 52 | ||
53 | m_scene.AddCommand( | 53 | m_scene.AddCommand( |
54 | this, "alert", "alert <message>", | 54 | "Users", this, "alert", "alert <message>", |
55 | "Send an alert to everyone", | 55 | "Send an alert to everyone", |
56 | HandleAlertConsoleCommand); | 56 | HandleAlertConsoleCommand); |
57 | 57 | ||
58 | m_scene.AddCommand( | 58 | m_scene.AddCommand( |
59 | this, "alert-user", "alert-user <first> <last> <message>", | 59 | "Users", this, "alert-user", "alert-user <first> <last> <message>", |
60 | "Send an alert to a user", | 60 | "Send an alert to a user", |
61 | HandleAlertConsoleCommand); | 61 | HandleAlertConsoleCommand); |
62 | } | 62 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index c266fe5..be767c4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
212 | scene.EventManager.OnClientLogin += OnClientLogin; | 212 | scene.EventManager.OnClientLogin += OnClientLogin; |
213 | } | 213 | } |
214 | 214 | ||
215 | public void RegionLoaded(Scene scene) | 215 | public virtual void RegionLoaded(Scene scene) |
216 | { | 216 | { |
217 | } | 217 | } |
218 | 218 | ||
@@ -550,7 +550,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
550 | UUID principalID = new UUID(im.fromAgentID); | 550 | UUID principalID = new UUID(im.fromAgentID); |
551 | UUID friendID = new UUID(im.toAgentID); | 551 | UUID friendID = new UUID(im.toAgentID); |
552 | 552 | ||
553 | m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2}", principalID, im.fromAgentName, friendID); | 553 | m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName); |
554 | |||
555 | // Check that the friendship doesn't exist yet | ||
556 | FriendInfo[] finfos = GetFriends(principalID); | ||
557 | if (finfos != null) | ||
558 | { | ||
559 | FriendInfo f = GetFriend(finfos, friendID); | ||
560 | if (f != null) | ||
561 | { | ||
562 | client.SendAgentAlertMessage("This person is already your friend. Please delete it first if you want to reestablish the friendship.", false); | ||
563 | return; | ||
564 | } | ||
565 | } | ||
554 | 566 | ||
555 | // This user wants to be friends with the other user. | 567 | // This user wants to be friends with the other user. |
556 | // Let's add the relation backwards, in case the other is not online | 568 | // Let's add the relation backwards, in case the other is not online |
@@ -561,7 +573,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
561 | } | 573 | } |
562 | } | 574 | } |
563 | 575 | ||
564 | private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) | 576 | protected virtual bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) |
565 | { | 577 | { |
566 | // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) | 578 | // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) |
567 | // We stick this agent's ID as imSession, so that it's directly available on the receiving end | 579 | // We stick this agent's ID as imSession, so that it's directly available on the receiving end |
@@ -570,7 +582,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
570 | 582 | ||
571 | // Try the local sim | 583 | // Try the local sim |
572 | if (LocalFriendshipOffered(friendID, im)) | 584 | if (LocalFriendshipOffered(friendID, im)) |
573 | return; | 585 | return true; |
574 | 586 | ||
575 | // The prospective friend is not here [as root]. Let's forward. | 587 | // The prospective friend is not here [as root]. Let's forward. |
576 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); | 588 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); |
@@ -581,9 +593,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
581 | { | 593 | { |
582 | GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); | 594 | GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); |
583 | m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message); | 595 | m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message); |
596 | return true; | ||
584 | } | 597 | } |
585 | } | 598 | } |
586 | // If the prospective friend is not online, he'll get the message upon login. | 599 | // If the prospective friend is not online, he'll get the message upon login. |
600 | return false; | ||
587 | } | 601 | } |
588 | 602 | ||
589 | protected virtual string GetFriendshipRequesterName(UUID agentID) | 603 | protected virtual string GetFriendshipRequesterName(UUID agentID) |
@@ -592,7 +606,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
592 | return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; | 606 | return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; |
593 | } | 607 | } |
594 | 608 | ||
595 | private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) | 609 | protected virtual void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) |
596 | { | 610 | { |
597 | m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID); | 611 | m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID); |
598 | 612 | ||
@@ -603,7 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
603 | { | 617 | { |
604 | StoreFriendships(client.AgentId, friendID); | 618 | StoreFriendships(client.AgentId, friendID); |
605 | 619 | ||
606 | // Update the local cache | 620 | // Update the local cache. |
607 | RecacheFriends(client); | 621 | RecacheFriends(client); |
608 | 622 | ||
609 | // | 623 | // |
@@ -756,7 +770,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
756 | 770 | ||
757 | #region Local | 771 | #region Local |
758 | 772 | ||
759 | public bool LocalFriendshipOffered(UUID toID, GridInstantMessage im) | 773 | public virtual bool LocalFriendshipOffered(UUID toID, GridInstantMessage im) |
760 | { | 774 | { |
761 | IClientAPI friendClient = LocateClientObject(toID); | 775 | IClientAPI friendClient = LocateClientObject(toID); |
762 | if (friendClient != null) | 776 | if (friendClient != null) |
@@ -912,7 +926,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
912 | return FriendsService.GetFriends(client.AgentId); | 926 | return FriendsService.GetFriends(client.AgentId); |
913 | } | 927 | } |
914 | 928 | ||
915 | private void RecacheFriends(IClientAPI client) | 929 | protected void RecacheFriends(IClientAPI client) |
916 | { | 930 | { |
917 | // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event | 931 | // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event |
918 | // is on the critical path for transferring an avatar from one region to another. | 932 | // is on the critical path for transferring an avatar from one region to another. |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 9c53fc4..e50a84a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | 52 | ||
53 | IUserManagement m_uMan; | 53 | IUserManagement m_uMan; |
54 | IUserManagement UserManagementModule | 54 | public IUserManagement UserManagementModule |
55 | { | 55 | { |
56 | get | 56 | get |
57 | { | 57 | { |
@@ -61,6 +61,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | protected HGFriendsServicesConnector m_HGFriendsConnector = new HGFriendsServicesConnector(); | ||
65 | protected HGStatusNotifier m_StatusNotifier; | ||
66 | |||
64 | #region ISharedRegionModule | 67 | #region ISharedRegionModule |
65 | public override string Name | 68 | public override string Name |
66 | { | 69 | { |
@@ -76,6 +79,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
76 | scene.RegisterModuleInterface<IFriendsSimConnector>(this); | 79 | scene.RegisterModuleInterface<IFriendsSimConnector>(this); |
77 | } | 80 | } |
78 | 81 | ||
82 | public override void RegionLoaded(Scene scene) | ||
83 | { | ||
84 | if (!m_Enabled) | ||
85 | return; | ||
86 | if (m_StatusNotifier == null) | ||
87 | m_StatusNotifier = new HGStatusNotifier(this); | ||
88 | } | ||
89 | |||
79 | #endregion | 90 | #endregion |
80 | 91 | ||
81 | #region IFriendsSimConnector | 92 | #region IFriendsSimConnector |
@@ -94,6 +105,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
94 | 105 | ||
95 | #endregion | 106 | #endregion |
96 | 107 | ||
108 | protected override void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) | ||
109 | { | ||
110 | // Update the local cache. Yes, we need to do it right here | ||
111 | // because the HGFriendsService placed something on the DB | ||
112 | // from under the sim | ||
113 | base.OnApproveFriendRequest(client, agentID, friendID, callingCardFolders); | ||
114 | } | ||
115 | |||
97 | protected override bool CacheFriends(IClientAPI client) | 116 | protected override bool CacheFriends(IClientAPI client) |
98 | { | 117 | { |
99 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name); | 118 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name); |
@@ -183,91 +202,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
183 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID); | 202 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID); |
184 | } | 203 | } |
185 | 204 | ||
186 | //protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online) | ||
187 | //{ | ||
188 | // // Let's single out the UUIs | ||
189 | // List<string> localFriends = new List<string>(); | ||
190 | // List<string> foreignFriends = new List<string>(); | ||
191 | // string tmp = string.Empty; | ||
192 | |||
193 | // foreach (string s in friendList) | ||
194 | // { | ||
195 | // UUID id; | ||
196 | // if (UUID.TryParse(s, out id)) | ||
197 | // localFriends.Add(s); | ||
198 | // else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp)) | ||
199 | // { | ||
200 | // foreignFriends.Add(s); | ||
201 | // // add it here too, who knows maybe the foreign friends happens to be on this grid | ||
202 | // localFriends.Add(id.ToString()); | ||
203 | // } | ||
204 | // } | ||
205 | |||
206 | // // OK, see who's present on this grid | ||
207 | // List<string> toBeRemoved = new List<string>(); | ||
208 | // PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray()); | ||
209 | // foreach (PresenceInfo pi in presence) | ||
210 | // { | ||
211 | // UUID presenceID; | ||
212 | // if (UUID.TryParse(pi.UserID, out presenceID)) | ||
213 | // { | ||
214 | // online.Add(presenceID); | ||
215 | // foreach (string s in foreignFriends) | ||
216 | // if (s.StartsWith(pi.UserID)) | ||
217 | // toBeRemoved.Add(s); | ||
218 | // } | ||
219 | // } | ||
220 | |||
221 | // foreach (string s in toBeRemoved) | ||
222 | // foreignFriends.Remove(s); | ||
223 | |||
224 | // // OK, let's send this up the stack, and leave a closure here | ||
225 | // // collecting online friends in other grids | ||
226 | // Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); }); | ||
227 | |||
228 | //} | ||
229 | |||
230 | //private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends) | ||
231 | //{ | ||
232 | // // let's divide the friends on a per-domain basis | ||
233 | // Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>(); | ||
234 | // foreach (string friend in foreignFriends) | ||
235 | // { | ||
236 | // UUID friendID; | ||
237 | // if (!UUID.TryParse(friend, out friendID)) | ||
238 | // { | ||
239 | // // it's a foreign friend | ||
240 | // string url = string.Empty, tmp = string.Empty; | ||
241 | // if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp)) | ||
242 | // { | ||
243 | // if (!friendsPerDomain.ContainsKey(url)) | ||
244 | // friendsPerDomain[url] = new List<string>(); | ||
245 | // friendsPerDomain[url].Add(friend); | ||
246 | // } | ||
247 | // } | ||
248 | // } | ||
249 | |||
250 | // // Now, call those worlds | ||
251 | |||
252 | // foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain) | ||
253 | // { | ||
254 | // List<string> ids = new List<string>(); | ||
255 | // foreach (string f in kvp.Value) | ||
256 | // ids.Add(f); | ||
257 | // UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); | ||
258 | // List<UUID> online = uConn.GetOnlineFriends(userID, ids); | ||
259 | // // Finally send the notifications to the user | ||
260 | // // this whole process may take a while, so let's check at every | ||
261 | // // iteration that the user is still here | ||
262 | // IClientAPI client = LocateClientObject(userID); | ||
263 | // if (client != null) | ||
264 | // client.SendAgentOnline(online.ToArray()); | ||
265 | // else | ||
266 | // break; | ||
267 | // } | ||
268 | |||
269 | //} | ||
270 | |||
271 | protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) | 205 | protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) |
272 | { | 206 | { |
273 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); | 207 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); |
@@ -305,25 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
305 | if (friendsPerDomain.ContainsKey("local")) | 239 | if (friendsPerDomain.ContainsKey("local")) |
306 | base.StatusNotify(friendsPerDomain["local"], userID, online); | 240 | base.StatusNotify(friendsPerDomain["local"], userID, online); |
307 | 241 | ||
308 | foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain) | 242 | m_StatusNotifier.Notify(userID, friendsPerDomain, online); |
309 | { | ||
310 | if (kvp.Key != "local") | ||
311 | { | ||
312 | // For the others, call the user agent service | ||
313 | List<string> ids = new List<string>(); | ||
314 | foreach (FriendInfo f in kvp.Value) | ||
315 | ids.Add(f.Friend); | ||
316 | UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); | ||
317 | List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online); | ||
318 | |||
319 | if (online && friendsOnline.Count > 0) | ||
320 | { | ||
321 | IClientAPI client = LocateClientObject(userID); | ||
322 | if (client != null) | ||
323 | client.SendAgentOnline(friendsOnline.ToArray()); | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | 243 | ||
328 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID); | 244 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID); |
329 | } | 245 | } |
@@ -335,26 +251,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
335 | return true; | 251 | return true; |
336 | 252 | ||
337 | // fid is not a UUID... | 253 | // fid is not a UUID... |
338 | string url = string.Empty, tmp = string.Empty; | 254 | string url = string.Empty, tmp = string.Empty, f = string.Empty, l = string.Empty; |
339 | if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp)) | 255 | if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out f, out l, out tmp)) |
340 | { | 256 | { |
341 | IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); | 257 | if (!agentID.Equals(UUID.Zero)) |
342 | userMan.AddUser(agentID, first, last, url); | 258 | { |
259 | m_uMan.AddUser(agentID, f, l, url); | ||
343 | 260 | ||
344 | return true; | 261 | string name = m_uMan.GetUserName(agentID); |
262 | string[] parts = name.Trim().Split(new char[] { ' ' }); | ||
263 | if (parts.Length == 2) | ||
264 | { | ||
265 | first = parts[0]; | ||
266 | last = parts[1]; | ||
267 | } | ||
268 | else | ||
269 | { | ||
270 | first = f; | ||
271 | last = l; | ||
272 | } | ||
273 | return true; | ||
274 | } | ||
345 | } | 275 | } |
346 | return false; | 276 | return false; |
347 | } | 277 | } |
348 | 278 | ||
349 | protected override string GetFriendshipRequesterName(UUID agentID) | 279 | protected override string GetFriendshipRequesterName(UUID agentID) |
350 | { | 280 | { |
351 | // For the time being we assume that HG friendship requests can only happen | 281 | return m_uMan.GetUserName(agentID); |
352 | // when avies are on the same region. | ||
353 | IClientAPI client = LocateClientObject(agentID); | ||
354 | if (client != null) | ||
355 | return client.FirstName + " " + client.LastName; | ||
356 | else | ||
357 | return base.GetFriendshipRequesterName(agentID); | ||
358 | } | 282 | } |
359 | 283 | ||
360 | protected override string FriendshipMessage(string friendID) | 284 | protected override string FriendshipMessage(string friendID) |
@@ -392,10 +316,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
392 | AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); | 316 | AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); |
393 | if (agentClientCircuit != null) | 317 | if (agentClientCircuit != null) |
394 | { | 318 | { |
395 | string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); | 319 | //[XXX] string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); |
396 | 320 | ||
397 | finfos = FriendsService.GetFriends(agentUUI); | 321 | finfos = FriendsService.GetFriends(client.AgentId.ToString()); |
398 | m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); | 322 | m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString()); |
399 | } | 323 | } |
400 | 324 | ||
401 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name); | 325 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name); |
@@ -454,16 +378,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
454 | friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); | 378 | friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); |
455 | } | 379 | } |
456 | 380 | ||
457 | // Are they both local users? | 381 | // Is the requester a local user? |
458 | if (agentIsLocal && friendIsLocal) | 382 | if (agentIsLocal) |
459 | { | 383 | { |
460 | // local grid users | 384 | // local grid users |
461 | m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local"); | 385 | m_log.DebugFormat("[HGFRIENDS MODULE]: Friendship requester is local. Storing backwards."); |
386 | |||
462 | base.StoreBackwards(friendID, agentID); | 387 | base.StoreBackwards(friendID, agentID); |
463 | return; | 388 | return; |
464 | } | 389 | } |
465 | 390 | ||
466 | // no provision for this temporary friendship state | 391 | // no provision for this temporary friendship state when user is not local |
467 | //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0); | 392 | //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0); |
468 | } | 393 | } |
469 | 394 | ||
@@ -501,12 +426,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
501 | agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); | 426 | agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); |
502 | agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); | 427 | agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); |
503 | agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); | 428 | agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); |
429 | RecacheFriends(agentClient); | ||
504 | } | 430 | } |
505 | if (friendClient != null) | 431 | if (friendClient != null) |
506 | { | 432 | { |
507 | friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); | 433 | friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); |
508 | friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); | 434 | friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); |
509 | friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); | 435 | friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); |
436 | RecacheFriends(friendClient); | ||
510 | } | 437 | } |
511 | 438 | ||
512 | m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", | 439 | m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", |
@@ -515,14 +442,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
515 | // Generate a random 8-character hex number that will sign this friendship | 442 | // Generate a random 8-character hex number that will sign this friendship |
516 | string secret = UUID.Random().ToString().Substring(0, 8); | 443 | string secret = UUID.Random().ToString().Substring(0, 8); |
517 | 444 | ||
445 | string theFriendUUID = friendUUI + ";" + secret; | ||
446 | string agentUUID = agentUUI + ";" + secret; | ||
447 | |||
518 | if (agentIsLocal) // agent is local, 'friend' is foreigner | 448 | if (agentIsLocal) // agent is local, 'friend' is foreigner |
519 | { | 449 | { |
520 | // This may happen when the agent returned home, in which case the friend is not there | 450 | // This may happen when the agent returned home, in which case the friend is not there |
521 | // We need to look for its information in the friends list itself | 451 | // We need to look for its information in the friends list itself |
452 | FriendInfo[] finfos = null; | ||
522 | bool confirming = false; | 453 | bool confirming = false; |
523 | if (friendUUI == string.Empty) | 454 | if (friendUUI == string.Empty) |
524 | { | 455 | { |
525 | FriendInfo[] finfos = GetFriends(agentID); | 456 | finfos = GetFriends(agentID); |
526 | foreach (FriendInfo finfo in finfos) | 457 | foreach (FriendInfo finfo in finfos) |
527 | { | 458 | { |
528 | if (finfo.TheirFlags == -1) | 459 | if (finfo.TheirFlags == -1) |
@@ -530,29 +461,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
530 | if (finfo.Friend.StartsWith(friendID.ToString())) | 461 | if (finfo.Friend.StartsWith(friendID.ToString())) |
531 | { | 462 | { |
532 | friendUUI = finfo.Friend; | 463 | friendUUI = finfo.Friend; |
464 | theFriendUUID = friendUUI; | ||
465 | UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty; | ||
466 | // If it's confirming the friendship, we already have the full UUI with the secret | ||
467 | if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret)) | ||
468 | { | ||
469 | agentUUID = agentUUI + ";" + secret; | ||
470 | m_uMan.AddUser(utmp, first, last, url); | ||
471 | } | ||
533 | confirming = true; | 472 | confirming = true; |
473 | break; | ||
534 | } | 474 | } |
535 | } | 475 | } |
536 | } | 476 | } |
537 | } | 477 | if (!confirming) |
478 | { | ||
479 | friendUUI = m_uMan.GetUserUUI(friendID); | ||
480 | theFriendUUID = friendUUI + ";" + secret; | ||
481 | } | ||
482 | |||
483 | friendFriendService = m_uMan.GetUserServerURL(friendID, "FriendsServerURI"); | ||
484 | |||
485 | // m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", | ||
486 | // agentUUI, friendUUI, agentFriendService, friendFriendService); | ||
538 | 487 | ||
539 | // If it's confirming the friendship, we already have the full friendUUI with the secret | 488 | } |
540 | string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret; | 489 | |
490 | // Delete any previous friendship relations | ||
491 | DeletePreviousRelations(agentID, friendID); | ||
541 | 492 | ||
542 | // store in the local friends service a reference to the foreign friend | 493 | // store in the local friends service a reference to the foreign friend |
543 | FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1); | 494 | FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1); |
544 | // and also the converse | 495 | // and also the converse |
545 | FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1); | 496 | FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1); |
546 | 497 | ||
547 | if (!confirming && friendClientCircuit != null) | 498 | //if (!confirming) |
548 | { | 499 | //{ |
549 | // store in the foreign friends service a reference to the local agent | 500 | // store in the foreign friends service a reference to the local agent |
550 | HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); | 501 | HGFriendsServicesConnector friendsConn = null; |
551 | friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); | 502 | if (friendClientCircuit != null) // the friend is here, validate session |
552 | } | 503 | friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); |
504 | else // the friend is not here, he initiated the request in his home world | ||
505 | friendsConn = new HGFriendsServicesConnector(friendFriendService); | ||
506 | |||
507 | friendsConn.NewFriendship(friendID, agentUUID); | ||
508 | //} | ||
553 | } | 509 | } |
554 | else if (friendIsLocal) // 'friend' is local, agent is foreigner | 510 | else if (friendIsLocal) // 'friend' is local, agent is foreigner |
555 | { | 511 | { |
512 | // Delete any previous friendship relations | ||
513 | DeletePreviousRelations(agentID, friendID); | ||
514 | |||
556 | // store in the local friends service a reference to the foreign agent | 515 | // store in the local friends service a reference to the foreign agent |
557 | FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1); | 516 | FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1); |
558 | // and also the converse | 517 | // and also the converse |
@@ -582,6 +541,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
582 | // my brain hurts now | 541 | // my brain hurts now |
583 | } | 542 | } |
584 | 543 | ||
544 | private void DeletePreviousRelations(UUID a1, UUID a2) | ||
545 | { | ||
546 | // Delete any previous friendship relations | ||
547 | FriendInfo[] finfos = null; | ||
548 | FriendInfo f = null; | ||
549 | finfos = GetFriends(a1); | ||
550 | if (finfos != null) | ||
551 | { | ||
552 | f = GetFriend(finfos, a2); | ||
553 | if (f != null) | ||
554 | { | ||
555 | FriendsService.Delete(a1, f.Friend); | ||
556 | // and also the converse | ||
557 | FriendsService.Delete(f.Friend, a1.ToString()); | ||
558 | } | ||
559 | } | ||
560 | |||
561 | finfos = GetFriends(a2); | ||
562 | if (finfos != null) | ||
563 | { | ||
564 | f = GetFriend(finfos, a1); | ||
565 | if (f != null) | ||
566 | { | ||
567 | FriendsService.Delete(a2, f.Friend); | ||
568 | // and also the converse | ||
569 | FriendsService.Delete(f.Friend, a2.ToString()); | ||
570 | } | ||
571 | } | ||
572 | } | ||
573 | |||
585 | protected override bool DeleteFriendship(UUID agentID, UUID exfriendID) | 574 | protected override bool DeleteFriendship(UUID agentID, UUID exfriendID) |
586 | { | 575 | { |
587 | Boolean agentIsLocal = true; | 576 | Boolean agentIsLocal = true; |
@@ -684,5 +673,80 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
684 | friendConn.DeleteFriendship(foreignUser, localUser, secret); | 673 | friendConn.DeleteFriendship(foreignUser, localUser, secret); |
685 | } | 674 | } |
686 | } | 675 | } |
676 | |||
677 | protected override bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) | ||
678 | { | ||
679 | if (base.ForwardFriendshipOffer(agentID, friendID, im)) | ||
680 | return true; | ||
681 | |||
682 | // OK, that didn't work, so let's try to find this user somewhere | ||
683 | if (!m_uMan.IsLocalGridUser(friendID)) | ||
684 | { | ||
685 | string friendsURL = m_uMan.GetUserServerURL(friendID, "FriendsServerURI"); | ||
686 | if (friendsURL != string.Empty) | ||
687 | { | ||
688 | m_log.DebugFormat("[HGFRIENDS MODULE]: Forwading friendship from {0} to {1} @ {2}", agentID, friendID, friendsURL); | ||
689 | GridRegion region = new GridRegion(); | ||
690 | region.ServerURI = friendsURL; | ||
691 | |||
692 | string name = im.fromAgentName; | ||
693 | if (m_uMan.IsLocalGridUser(agentID)) | ||
694 | { | ||
695 | IClientAPI agentClient = LocateClientObject(agentID); | ||
696 | AgentCircuitData agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); | ||
697 | string agentHomeService = string.Empty; | ||
698 | try | ||
699 | { | ||
700 | agentHomeService = agentClientCircuit.ServiceURLs["HomeURI"].ToString(); | ||
701 | string lastname = "@" + new Uri(agentHomeService).Authority; | ||
702 | string firstname = im.fromAgentName.Replace(" ", "."); | ||
703 | name = firstname + lastname; | ||
704 | } | ||
705 | catch (KeyNotFoundException) | ||
706 | { | ||
707 | m_log.DebugFormat("[HGFRIENDS MODULE]: Key HomeURI not found for user {0}", agentID); | ||
708 | return false; | ||
709 | } | ||
710 | catch (NullReferenceException) | ||
711 | { | ||
712 | m_log.DebugFormat("[HGFRIENDS MODULE]: Null HomeUri for local user {0}", agentID); | ||
713 | return false; | ||
714 | } | ||
715 | catch (UriFormatException) | ||
716 | { | ||
717 | m_log.DebugFormat("[HGFRIENDS MODULE]: Malformed HomeUri {0} for local user {1}", agentHomeService, agentID); | ||
718 | return false; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | m_HGFriendsConnector.FriendshipOffered(region, agentID, friendID, im.message, name); | ||
723 | |||
724 | return true; | ||
725 | } | ||
726 | } | ||
727 | |||
728 | return false; | ||
729 | } | ||
730 | |||
731 | public override bool LocalFriendshipOffered(UUID toID, GridInstantMessage im) | ||
732 | { | ||
733 | if (base.LocalFriendshipOffered(toID, im)) | ||
734 | { | ||
735 | if (im.fromAgentName.Contains("@")) | ||
736 | { | ||
737 | string[] parts = im.fromAgentName.Split(new char[] { '@' }); | ||
738 | if (parts.Length == 2) | ||
739 | { | ||
740 | string[] fl = parts[0].Trim().Split(new char[] { '.' }); | ||
741 | if (fl.Length == 2) | ||
742 | m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], fl[1], "http://" + parts[1]); | ||
743 | else | ||
744 | m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], "", "http://" + parts[1]); | ||
745 | } | ||
746 | } | ||
747 | return true; | ||
748 | } | ||
749 | return false; | ||
750 | } | ||
687 | } | 751 | } |
688 | } \ No newline at end of file | 752 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGStatusNotifier.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGStatusNotifier.cs new file mode 100644 index 0000000..1fa4dd6 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGStatusNotifier.cs | |||
@@ -0,0 +1,69 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Linq; | ||
4 | using System.Reflection; | ||
5 | using System.Text; | ||
6 | using OpenSim.Framework; | ||
7 | using OpenSim.Region.Framework.Interfaces; | ||
8 | using OpenSim.Services.Interfaces; | ||
9 | using OpenSim.Services.Connectors.Hypergrid; | ||
10 | using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; | ||
11 | |||
12 | using OpenMetaverse; | ||
13 | |||
14 | using log4net; | ||
15 | |||
16 | namespace OpenSim.Region.CoreModules.Avatar.Friends | ||
17 | { | ||
18 | public class HGStatusNotifier | ||
19 | { | ||
20 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
21 | |||
22 | private HGFriendsModule m_FriendsModule; | ||
23 | |||
24 | public HGStatusNotifier(HGFriendsModule friendsModule) | ||
25 | { | ||
26 | m_FriendsModule = friendsModule; | ||
27 | } | ||
28 | |||
29 | public void Notify(UUID userID, Dictionary<string, List<FriendInfo>> friendsPerDomain, bool online) | ||
30 | { | ||
31 | foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain) | ||
32 | { | ||
33 | if (kvp.Key != "local") | ||
34 | { | ||
35 | // For the others, call the user agent service | ||
36 | List<string> ids = new List<string>(); | ||
37 | foreach (FriendInfo f in kvp.Value) | ||
38 | ids.Add(f.Friend); | ||
39 | |||
40 | if (ids.Count == 0) | ||
41 | continue; // no one to notify. caller don't do this | ||
42 | |||
43 | m_log.DebugFormat("[HG STATUS NOTIFIER]: Notifying {0} friends in {1}", ids.Count, kvp.Key); | ||
44 | // ASSUMPTION: we assume that all users for one home domain | ||
45 | // have exactly the same set of service URLs. | ||
46 | // If this is ever not true, we need to change this. | ||
47 | UUID friendID = UUID.Zero; String tmp = String.Empty; | ||
48 | if (Util.ParseUniversalUserIdentifier(ids[0], out friendID, out tmp, out tmp, out tmp, out tmp)) | ||
49 | { | ||
50 | string friendsServerURI = m_FriendsModule.UserManagementModule.GetUserServerURL(friendID, "FriendsServerURI"); | ||
51 | if (friendsServerURI != string.Empty) | ||
52 | { | ||
53 | HGFriendsServicesConnector fConn = new HGFriendsServicesConnector(friendsServerURI); | ||
54 | |||
55 | List<UUID> friendsOnline = fConn.StatusNotification(ids, userID, online); | ||
56 | |||
57 | if (online && friendsOnline.Count > 0) | ||
58 | { | ||
59 | IClientAPI client = m_FriendsModule.LocateClientObject(userID); | ||
60 | if (client != null) | ||
61 | client.SendAgentOnline(friendsOnline.ToArray()); | ||
62 | } | ||
63 | } | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | } | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 5238325..a26c73a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -270,12 +270,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
270 | 270 | ||
271 | m_archiveWriter = new TarArchiveWriter(m_saveStream); | 271 | m_archiveWriter = new TarArchiveWriter(m_saveStream); |
272 | 272 | ||
273 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive."); | ||
274 | |||
273 | // Write out control file. This has to be done first so that subsequent loaders will see this file first | 275 | // Write out control file. This has to be done first so that subsequent loaders will see this file first |
274 | // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this | 276 | // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this |
275 | // not sure how to fix this though, short of going with a completely different file format. | 277 | // not sure how to fix this though, short of going with a completely different file format. |
276 | m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options)); | 278 | m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options)); |
277 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Added control file to archive."); | 279 | |
278 | |||
279 | if (inventoryFolder != null) | 280 | if (inventoryFolder != null) |
280 | { | 281 | { |
281 | m_log.DebugFormat( | 282 | m_log.DebugFormat( |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 650069a..ac22c3f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
108 | OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; | 108 | OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; |
109 | 109 | ||
110 | scene.AddCommand( | 110 | scene.AddCommand( |
111 | this, "load iar", | 111 | "Archiving", this, "load iar", |
112 | "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]", | 112 | "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]", |
113 | "Load user inventory archive (IAR).", | 113 | "Load user inventory archive (IAR).", |
114 | "-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones" | 114 | "-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones" |
@@ -121,18 +121,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
121 | HandleLoadInvConsoleCommand); | 121 | HandleLoadInvConsoleCommand); |
122 | 122 | ||
123 | scene.AddCommand( | 123 | scene.AddCommand( |
124 | this, "save iar", | 124 | "Archiving", this, "save iar", |
125 | "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]", | 125 | "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]", |
126 | "Save user inventory archive (IAR).", | 126 | "Save user inventory archive (IAR).", |
127 | "<first> is the user's first name." + Environment.NewLine | 127 | "<first> is the user's first name.\n" |
128 | + "<last> is the user's last name." + Environment.NewLine | 128 | + "<last> is the user's last name.\n" |
129 | + "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine | 129 | + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n" |
130 | + "-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine | ||
131 | + "-c|--creators preserves information about foreign creators." + Environment.NewLine | ||
132 | + "-v|--verbose extra debug messages." + Environment.NewLine | ||
133 | + "--noassets stops assets being saved to the IAR." | ||
134 | + "<IAR path> is the filesystem path at which to save the IAR." | 130 | + "<IAR path> is the filesystem path at which to save the IAR." |
135 | + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), | 131 | + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME) |
132 | + "-h|--home=<url> adds the url of the profile service to the saved user information.\n" | ||
133 | + "-c|--creators preserves information about foreign creators.\n" | ||
134 | + "-v|--verbose extra debug messages.\n" | ||
135 | + "--noassets stops assets being saved to the IAR.", | ||
136 | HandleSaveInvConsoleCommand); | 136 | HandleSaveInvConsoleCommand); |
137 | 137 | ||
138 | m_aScene = scene; | 138 | m_aScene = scene; |