aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs212
1 files changed, 151 insertions, 61 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index abffb94..c55839f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -72,8 +72,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
72 UUID id; 72 UUID id;
73 if (!UUID.TryParse(finfo.Friend, out id)) 73 if (!UUID.TryParse(finfo.Friend, out id))
74 { 74 {
75 string url = string.Empty, first = string.Empty, last = string.Empty; 75 string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
76 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last)) 76 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
77 { 77 {
78 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); 78 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
79 uMan.AddUser(id, url + ";" + first + " " + last); 79 uMan.AddUser(id, url + ";" + first + " " + last);
@@ -103,22 +103,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
103 return false; 103 return false;
104 } 104 }
105 105
106 protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
107 {
108 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
109 if (account1 != null)
110 return base.GetFriendsFromService(client);
111
112 // Foreigner
113 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
114 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
115
116 FriendInfo[] finfos = FriendsService.GetFriends(agentUUI);
117 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
118 return finfos;
119 }
120
121
122 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) 106 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
123 { 107 {
124 first = "Unknown"; last = "User"; 108 first = "Unknown"; last = "User";
@@ -126,8 +110,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
126 return true; 110 return true;
127 111
128 // fid is not a UUID... 112 // fid is not a UUID...
129 string url = string.Empty; 113 string url = string.Empty, tmp = string.Empty;
130 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last)) 114 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
131 { 115 {
132 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); 116 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
133 userMan.AddUser(agentID, url + ";" + first + " " + last); 117 userMan.AddUser(agentID, url + ";" + first + " " + last);
@@ -164,7 +148,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
164 return "Please confirm this friendship you made while you were away."; 148 return "Please confirm this friendship you made while you were away.";
165 } 149 }
166 150
167 protected override bool SimpleStore(UUID agentID, UUID friendID, int rights) 151 protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
152 {
153 foreach (FriendInfo fi in friends)
154 {
155 if (fi.Friend.StartsWith(friendID.ToString()))
156 return fi;
157 }
158 return null;
159 }
160
161
162 protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
163 {
164 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
165 if (account1 != null)
166 return base.GetFriendsFromService(client);
167
168 FriendInfo[] finfos = new FriendInfo[0];
169 // Foreigner
170 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
171 if (agentClientCircuit != null)
172 {
173 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
174
175 m_log.DebugFormat("[XXX] GetFriendsFromService to {0}", agentUUI);
176 finfos = FriendsService.GetFriends(agentUUI);
177 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
178 }
179 return finfos;
180 }
181
182 protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
168 { 183 {
169 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); 184 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
170 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); 185 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
@@ -172,30 +187,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
172 if (account1 != null && account2 != null) 187 if (account1 != null && account2 != null)
173 { 188 {
174 // local grid users 189 // local grid users
175 return base.SimpleStore(agentID, friendID, rights); 190 return base.StoreRights(agentID, friendID, rights);
176 } 191 }
177 192
178 if (account1 != null) 193 if (account1 != null) // agent is local, friend is foreigner
179 { 194 {
180 FriendInfo[] finfos = GetFriends(agentID); 195 FriendInfo[] finfos = GetFriends(agentID);
181 if (finfos.Length > 0) 196 FriendInfo finfo = GetFriend(finfos, friendID);
197 if (finfo != null)
182 { 198 {
183 FriendInfo finfo = GetFriend(finfos, friendID);
184 FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights); 199 FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
185 return true; 200 return true;
186 } 201 }
187 } 202 }
188 if (account2 != null) 203
204 if (account2 != null) // agent is foreigner, friend is local
189 { 205 {
190 IClientAPI client = LocateClientObject(agentID); 206 string agentUUI = GetUUI(friendID, agentID);
191 if (client != null) 207 if (agentUUI != string.Empty)
192 { 208 {
193 AgentCircuitData acircuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); 209 FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
194 if (acircuit != null) 210 return true;
195 {
196 FriendsService.StoreFriend(Util.ProduceUserUniversalIdentifier(acircuit), friendID.ToString(), rights);
197 return true;
198 }
199 } 211 }
200 } 212 }
201 213
@@ -233,7 +245,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
233 return; 245 return;
234 } 246 }
235 247
236
237 // ok, at least one of them is foreigner, let's get their data 248 // ok, at least one of them is foreigner, let's get their data
238 IClientAPI agentClient = LocateClientObject(agentID); 249 IClientAPI agentClient = LocateClientObject(agentID);
239 IClientAPI friendClient = LocateClientObject(friendID); 250 IClientAPI friendClient = LocateClientObject(friendID);
@@ -257,13 +268,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
257 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); 268 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
258 } 269 }
259 270
260 m_log.DebugFormat("[XXX] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", 271 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
261 agentUUI, friendUUI, agentFriendService, friendFriendService); 272 agentUUI, friendUUI, agentFriendService, friendFriendService);
262 273
274 // Generate a random 8-character hex number that will sign this friendship
275 string secret = UUID.Random().ToString().Substring(0, 8);
276
263 if (agentAccount != null) // agent is local, 'friend' is foreigner 277 if (agentAccount != null) // agent is local, 'friend' is foreigner
264 { 278 {
265 // This may happen when the agent returned home, in which case the friend is not there 279 // This may happen when the agent returned home, in which case the friend is not there
266 // We need to llok for its information in the friends list itself 280 // We need to look for its information in the friends list itself
281 bool confirming = false;
267 if (friendUUI == string.Empty) 282 if (friendUUI == string.Empty)
268 { 283 {
269 FriendInfo[] finfos = GetFriends(agentID); 284 FriendInfo[] finfos = GetFriends(agentID);
@@ -272,35 +287,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
272 if (finfo.TheirFlags == -1) 287 if (finfo.TheirFlags == -1)
273 { 288 {
274 if (finfo.Friend.StartsWith(friendID.ToString())) 289 if (finfo.Friend.StartsWith(friendID.ToString()))
290 {
275 friendUUI = finfo.Friend; 291 friendUUI = finfo.Friend;
292 confirming = true;
293 }
276 } 294 }
277 } 295 }
278 } 296 }
279 297
298 // If it's confirming the friendship, we already have the full friendUUI with the secret
299 string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
300
280 // store in the local friends service a reference to the foreign friend 301 // store in the local friends service a reference to the foreign friend
281 FriendsService.StoreFriend(agentID.ToString(), friendUUI, 1); 302 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
282 // and also the converse 303 // and also the converse
283 FriendsService.StoreFriend(friendUUI, agentID.ToString(), 1); 304 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
284 305
285 if (friendClientCircuit != null) 306 if (!confirming && friendClientCircuit != null)
286 { 307 {
287 // store in the foreign friends service a reference to the local agent 308 // store in the foreign friends service a reference to the local agent
288 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); 309 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
289 friendsConn.NewFriendship(friendID, agentUUI); 310 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
290 } 311 }
291 } 312 }
292 else if (friendAccount != null) // 'friend' is local, agent is foreigner 313 else if (friendAccount != null) // 'friend' is local, agent is foreigner
293 { 314 {
294 // store in the local friends service a reference to the foreign agent 315 // store in the local friends service a reference to the foreign agent
295 FriendsService.StoreFriend(friendID.ToString(), agentUUI, 1); 316 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
296 // and also the converse 317 // and also the converse
297 FriendsService.StoreFriend(agentUUI, friendID.ToString(), 1); 318 FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
298 319
299 if (agentClientCircuit != null) 320 if (agentClientCircuit != null)
300 { 321 {
301 // store in the foreign friends service a reference to the local agent 322 // store in the foreign friends service a reference to the local agent
302 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); 323 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
303 friendsConn.NewFriendship(agentID, friendUUI); 324 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
304 } 325 }
305 } 326 }
306 else // They're both foreigners! 327 else // They're both foreigners!
@@ -309,43 +330,112 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
309 if (agentClientCircuit != null) 330 if (agentClientCircuit != null)
310 { 331 {
311 friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); 332 friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
312 friendsConn.NewFriendship(agentID, friendUUI); 333 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
313 } 334 }
314 if (friendClientCircuit != null) 335 if (friendClientCircuit != null)
315 { 336 {
316 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); 337 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
317 friendsConn.NewFriendship(friendID, agentUUI); 338 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
318 } 339 }
319 } 340 }
320 // my brain hurts now 341 // my brain hurts now
321 } 342 }
322 343
323 protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) 344 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
324 { 345 {
325 foreach (FriendInfo fi in friends) 346 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
347 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
348 // Are they both local users?
349 if (agentAccount != null && friendAccount != null)
326 { 350 {
327 if (fi.Friend.StartsWith(friendID.ToString())) 351 // local grid users
328 return fi; 352 return base.DeleteFriendship(agentID, exfriendID);
329 } 353 }
330 return null; 354
355 // ok, at least one of them is foreigner, let's get their data
356 string agentUUI = string.Empty;
357 string friendUUI = string.Empty;
358
359 if (agentAccount != null) // agent is local, 'friend' is foreigner
360 {
361 // We need to look for its information in the friends list itself
362 FriendInfo[] finfos = GetFriends(agentID);
363 FriendInfo finfo = GetFriend(finfos, exfriendID);
364 if (finfo != null)
365 {
366 friendUUI = finfo.Friend;
367
368 // delete in the local friends service the reference to the foreign friend
369 FriendsService.Delete(agentID, friendUUI);
370 // and also the converse
371 FriendsService.Delete(friendUUI, agentID.ToString());
372
373 // notify the exfriend's service
374 Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
375
376 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
377 return true;
378 }
379 }
380 else if (friendAccount != null) // agent is foreigner, 'friend' is local
381 {
382 agentUUI = GetUUI(exfriendID, agentID);
383
384 if (agentUUI != string.Empty)
385 {
386 // delete in the local friends service the reference to the foreign agent
387 FriendsService.Delete(exfriendID, agentUUI);
388 // and also the converse
389 FriendsService.Delete(agentUUI, exfriendID.ToString());
390
391 // notify the agent's service?
392 Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
393
394 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
395 return true;
396 }
397 }
398 //else They're both foreigners! Can't handle this
399
400 return false;
331 } 401 }
332 402
333 protected override void DeleteFriendship(UUID agentID, UUID exfriendID) 403 private string GetUUI(UUID localUser, UUID foreignUser)
334 { 404 {
335 base.DeleteFriendship(agentID, exfriendID); 405 // Let's see if the user is here by any chance
336 // Maybe some of the base deletes will fail. 406 FriendInfo[] finfos = GetFriends(localUser);
337 // Let's delete the local friendship with foreign friend 407 if (finfos != EMPTY_FRIENDS) // friend is here, cool
338 FriendInfo[] friends = GetFriends(agentID);
339 foreach (FriendInfo finfo in friends)
340 { 408 {
341 if (finfo.Friend != exfriendID.ToString() && finfo.Friend.StartsWith(exfriendID.ToString())) 409 FriendInfo finfo = GetFriend(finfos, foreignUser);
410 if (finfo != null)
342 { 411 {
343 FriendsService.Delete(agentID, exfriendID.ToString()); 412 return finfo.Friend;
344 // TODO: delete the friendship on the other side
345 // Should use the homeurl given in finfo.Friend
346 } 413 }
347 } 414 }
415 else // user is not currently on this sim, need to get from the service
416 {
417 finfos = FriendsService.GetFriends(localUser);
418 foreach (FriendInfo finfo in finfos)
419 {
420 if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
421 {
422 return finfo.Friend;
423 }
424 }
425 }
426 return string.Empty;
348 } 427 }
349 428
429 private void Delete(UUID foreignUser, UUID localUser, string uui)
430 {
431 UUID id;
432 string url = string.Empty, secret = string.Empty, tmp = string.Empty;
433 if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
434 {
435 m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
436 HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
437 friendConn.DeleteFriendship(foreignUser, localUser, secret);
438 }
439 }
350 } 440 }
351} 441}