aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
authorMelanie2011-06-09 02:05:04 +0100
committerMelanie2011-06-09 02:05:04 +0100
commit326c46ba70cea70ddfe4aef9a6b73edff63e126a (patch)
tree5e76347b0d77f58717d8e5e4f3b8787ff01a18d7 /OpenSim/Region/CoreModules
parentMake the last otem in a list created with llCSV2List findable (diff)
parentConsistency fix on the last commit. (diff)
downloadopensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.zip
opensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.gz
opensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.bz2
opensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.xz
Merge branch 'master' into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs355
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs628
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs350
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs82
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs244
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs15
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs173
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs35
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs57
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs34
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs84
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs112
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs25
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs23
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs41
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs83
21 files changed, 2137 insertions, 224 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index ded8743..8a16582 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -124,7 +124,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
124 124
125 ScenePresence sp = m_scene.GetScenePresence(avatarID); 125 ScenePresence sp = m_scene.GetScenePresence(avatarID);
126 if (sp != null) 126 if (sp != null)
127 sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); 127 sp.ControllingClient.SendDialog(
128 objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
128 } 129 }
129 130
130 public void SendUrlToUser( 131 public void SendUrlToUser(
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 0cd05e3..c8167c5 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
49{ 49{
50 public class FriendsModule : ISharedRegionModule, IFriendsModule 50 public class FriendsModule : ISharedRegionModule, IFriendsModule
51 { 51 {
52 protected bool m_Enabled = false;
53
52 protected class UserFriendData 54 protected class UserFriendData
53 { 55 {
54 public UUID PrincipalID; 56 public UUID PrincipalID;
@@ -67,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
67 } 69 }
68 } 70 }
69 71
70 private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; 72 protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
71 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 73 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
72 74
73 protected List<Scene> m_Scenes = new List<Scene>(); 75 protected List<Scene> m_Scenes = new List<Scene>();
@@ -130,8 +132,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
130 } 132 }
131 } 133 }
132 134
135 #region ISharedRegionModule
133 public void Initialise(IConfigSource config) 136 public void Initialise(IConfigSource config)
134 { 137 {
138 IConfig moduleConfig = config.Configs["Modules"];
139 if (moduleConfig != null)
140 {
141 string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
142 if (name == Name)
143 {
144 InitModule(config);
145
146 m_Enabled = true;
147 m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
148 }
149 }
150 }
151
152 protected void InitModule(IConfigSource config)
153 {
135 IConfig friendsConfig = config.Configs["Friends"]; 154 IConfig friendsConfig = config.Configs["Friends"];
136 if (friendsConfig != null) 155 if (friendsConfig != null)
137 { 156 {
@@ -153,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
153 m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue"); 172 m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
154 throw new Exception("Connector load error"); 173 throw new Exception("Connector load error");
155 } 174 }
156
157 } 175 }
158 176
159 public void PostInitialise() 177 public void PostInitialise()
@@ -164,8 +182,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
164 { 182 {
165 } 183 }
166 184
167 public void AddRegion(Scene scene) 185 public virtual void AddRegion(Scene scene)
168 { 186 {
187 if (!m_Enabled)
188 return;
189 m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
190
169 m_Scenes.Add(scene); 191 m_Scenes.Add(scene);
170 scene.RegisterModuleInterface<IFriendsModule>(this); 192 scene.RegisterModuleInterface<IFriendsModule>(this);
171 193
@@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
181 203
182 public void RemoveRegion(Scene scene) 204 public void RemoveRegion(Scene scene)
183 { 205 {
206 if (!m_Enabled)
207 return;
208
184 m_Scenes.Remove(scene); 209 m_Scenes.Remove(scene);
185 } 210 }
186 211
187 public string Name 212 public virtual string Name
188 { 213 {
189 get { return "FriendsModule"; } 214 get { return "FriendsModule"; }
190 } 215 }
@@ -194,13 +219,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
194 get { return null; } 219 get { return null; }
195 } 220 }
196 221
197 public uint GetFriendPerms(UUID principalID, UUID friendID) 222 #endregion
223
224 public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
198 { 225 {
199 FriendInfo[] friends = GetFriends(principalID); 226 FriendInfo[] friends = GetFriends(principalID);
200 foreach (FriendInfo fi in friends) 227 FriendInfo finfo = GetFriend(friends, friendID);
228 if (finfo != null)
201 { 229 {
202 if (fi.Friend == friendID.ToString()) 230 return (uint)finfo.TheirFlags;
203 return (uint)fi.TheirFlags;
204 } 231 }
205 232
206 return 0; 233 return 0;
@@ -214,30 +241,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
214 client.OnTerminateFriendship += OnTerminateFriendship; 241 client.OnTerminateFriendship += OnTerminateFriendship;
215 client.OnGrantUserRights += OnGrantUserRights; 242 client.OnGrantUserRights += OnGrantUserRights;
216 243
217 // Asynchronously fetch the friends list or increment the refcount for the existing 244 Util.FireAndForget(delegate { FetchFriendslist(client); });
218 // friends list 245 }
219 Util.FireAndForget( 246
220 delegate(object o) 247 /// Fetch the friends list or increment the refcount for the existing
248 /// friends list
249 /// Returns true if the list was fetched, false if it wasn't
250 protected virtual bool FetchFriendslist(IClientAPI client)
251 {
252 UUID agentID = client.AgentId;
253 lock (m_Friends)
254 {
255 UserFriendData friendsData;
256 if (m_Friends.TryGetValue(agentID, out friendsData))
221 { 257 {
222 lock (m_Friends) 258 friendsData.Refcount++;
223 { 259 return false;
224 UserFriendData friendsData; 260 }
225 if (m_Friends.TryGetValue(client.AgentId, out friendsData)) 261 else
226 { 262 {
227 friendsData.Refcount++; 263 friendsData = new UserFriendData();
228 } 264 friendsData.PrincipalID = agentID;
229 else 265 friendsData.Friends = GetFriendsFromService(client);
230 { 266 friendsData.Refcount = 1;
231 friendsData = new UserFriendData();
232 friendsData.PrincipalID = client.AgentId;
233 friendsData.Friends = FriendsService.GetFriends(client.AgentId);
234 friendsData.Refcount = 1;
235 267
236 m_Friends[client.AgentId] = friendsData; 268 m_Friends[agentID] = friendsData;
237 } 269 return true;
238 }
239 } 270 }
240 ); 271 }
241 } 272 }
242 273
243 private void OnClientClosed(UUID agentID, Scene scene) 274 private void OnClientClosed(UUID agentID, Scene scene)
@@ -263,14 +294,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
263 294
264 private void OnMakeRootAgent(ScenePresence sp) 295 private void OnMakeRootAgent(ScenePresence sp)
265 { 296 {
266 UUID agentID = sp.ControllingClient.AgentId; 297 RefetchFriends(sp.ControllingClient);
267 UpdateFriendsCache(agentID);
268 } 298 }
269 299
270 private void OnClientLogin(IClientAPI client) 300 private void OnClientLogin(IClientAPI client)
271 { 301 {
272 UUID agentID = client.AgentId; 302 UUID agentID = client.AgentId;
273 303
304 //m_log.DebugFormat("[XXX]: OnClientLogin!");
274 // Inform the friends that this user is online 305 // Inform the friends that this user is online
275 StatusChange(agentID, true); 306 StatusChange(agentID, true);
276 307
@@ -279,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
279 m_NeedsListOfFriends.Add(agentID); 310 m_NeedsListOfFriends.Add(agentID);
280 } 311 }
281 312
282 public void SendFriendsOnlineIfNeeded(IClientAPI client) 313 public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
283 { 314 {
284 UUID agentID = client.AgentId; 315 UUID agentID = client.AgentId;
285 316
@@ -287,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
287 lock (m_NeedsListOfFriends) 318 lock (m_NeedsListOfFriends)
288 { 319 {
289 if (!m_NeedsListOfFriends.Remove(agentID)) 320 if (!m_NeedsListOfFriends.Remove(agentID))
290 return; 321 return false;
291 } 322 }
292 323
293 // Send the friends online 324 // Send the friends online
@@ -313,10 +344,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
313 foreach (string fid in outstanding) 344 foreach (string fid in outstanding)
314 { 345 {
315 UUID fromAgentID; 346 UUID fromAgentID;
316 if (!UUID.TryParse(fid, out fromAgentID)) 347 string firstname = "Unknown", lastname = "User";
348 if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
349 {
350 m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
317 continue; 351 continue;
318 352 }
319 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
320 353
321 PresenceInfo presence = null; 354 PresenceInfo presence = null;
322 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); 355 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
@@ -326,13 +359,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
326 im.offline = 0; 359 im.offline = 0;
327 360
328 im.fromAgentID = fromAgentID.Guid; 361 im.fromAgentID = fromAgentID.Guid;
329 im.fromAgentName = account.FirstName + " " + account.LastName; 362 im.fromAgentName = firstname + " " + lastname;
330 im.offline = (byte)((presence == null) ? 1 : 0); 363 im.offline = (byte)((presence == null) ? 1 : 0);
331 im.imSessionID = im.fromAgentID; 364 im.imSessionID = im.fromAgentID;
365 im.message = FriendshipMessage(fid);
332 366
333 // Finally 367 // Finally
334 LocalFriendshipOffered(agentID, im); 368 LocalFriendshipOffered(agentID, im);
335 } 369 }
370
371 return true;
372 }
373
374 protected virtual string FriendshipMessage(string friendID)
375 {
376 return "Will you be my friend?";
377 }
378
379 protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
380 {
381 first = "Unknown"; last = "User";
382 if (!UUID.TryParse(fid, out agentID))
383 return false;
384
385 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID);
386 if (account != null)
387 {
388 first = account.FirstName;
389 last = account.LastName;
390 }
391
392 return true;
336 } 393 }
337 394
338 List<UUID> GetOnlineFriends(UUID userID) 395 List<UUID> GetOnlineFriends(UUID userID)
@@ -348,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
348 } 405 }
349 406
350 if (friendList.Count > 0) 407 if (friendList.Count > 0)
351 { 408 GetOnlineFriends(userID, friendList, online);
352 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
353 foreach (PresenceInfo pi in presence)
354 {
355 UUID presenceID;
356 if (UUID.TryParse(pi.UserID, out presenceID))
357 online.Add(presenceID);
358 }
359 }
360 409
361 return online; 410 return online;
362 } 411 }
363 412
413 protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
414 {
415 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
416 foreach (PresenceInfo pi in presence)
417 {
418 UUID presenceID;
419 if (UUID.TryParse(pi.UserID, out presenceID))
420 online.Add(presenceID);
421 }
422 }
423
364 /// <summary> 424 /// <summary>
365 /// Find the client for a ID 425 /// Find the client for a ID
366 /// </summary> 426 /// </summary>
@@ -415,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
415 Util.FireAndForget( 475 Util.FireAndForget(
416 delegate 476 delegate
417 { 477 {
418 foreach (FriendInfo fi in friendList) 478 m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
419 { 479 // Notify about this user status
420 //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID); 480 StatusNotify(friendList, agentID, online);
421 // Notify about this user status
422 StatusNotify(fi, agentID, online);
423 }
424 } 481 }
425 ); 482 );
426 } 483 }
427 } 484 }
428 485
429 private void StatusNotify(FriendInfo friend, UUID userID, bool online) 486 protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
430 { 487 {
431 UUID friendID; 488 foreach (FriendInfo friend in friendList)
432 if (UUID.TryParse(friend.Friend, out friendID))
433 { 489 {
434 // Try local 490 UUID friendID;
435 if (LocalStatusNotification(userID, friendID, online)) 491 if (UUID.TryParse(friend.Friend, out friendID))
436 return;
437
438 // The friend is not here [as root]. Let's forward.
439 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
440 if (friendSessions != null && friendSessions.Length > 0)
441 { 492 {
442 PresenceInfo friendSession = null; 493 // Try local
443 foreach (PresenceInfo pinfo in friendSessions) 494 if (LocalStatusNotification(userID, friendID, online))
444 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad 495 return;
445 {
446 friendSession = pinfo;
447 break;
448 }
449 496
450 if (friendSession != null) 497 // The friend is not here [as root]. Let's forward.
498 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
499 if (friendSessions != null && friendSessions.Length > 0)
451 { 500 {
452 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 501 PresenceInfo friendSession = null;
453 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); 502 foreach (PresenceInfo pinfo in friendSessions)
454 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); 503 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
504 {
505 friendSession = pinfo;
506 break;
507 }
508
509 if (friendSession != null)
510 {
511 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
512 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
513 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
514 }
455 } 515 }
456 }
457 516
458 // Friend is not online. Ignore. 517 // Friend is not online. Ignore.
459 } 518 }
460 else 519 else
461 { 520 {
462 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); 521 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
522 }
463 } 523 }
464 } 524 }
465 525
@@ -475,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
475 535
476 // This user wants to be friends with the other user. 536 // This user wants to be friends with the other user.
477 // Let's add the relation backwards, in case the other is not online 537 // Let's add the relation backwards, in case the other is not online
478 FriendsService.StoreFriend(friendID, principalID.ToString(), 0); 538 StoreBackwards(friendID, principalID);
479 539
480 // Now let's ask the other user to be friends with this user 540 // Now let's ask the other user to be friends with this user
481 ForwardFriendshipOffer(principalID, friendID, im); 541 ForwardFriendshipOffer(principalID, friendID, im);
@@ -487,11 +547,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
487 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) 547 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
488 // We stick this agent's ID as imSession, so that it's directly available on the receiving end 548 // We stick this agent's ID as imSession, so that it's directly available on the receiving end
489 im.imSessionID = im.fromAgentID; 549 im.imSessionID = im.fromAgentID;
550 im.fromAgentName = GetFriendshipRequesterName(agentID);
490 551
491 // Try the local sim 552 // Try the local sim
492 UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
493 im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
494
495 if (LocalFriendshipOffered(friendID, im)) 553 if (LocalFriendshipOffered(friendID, im))
496 return; 554 return;
497 555
@@ -509,12 +567,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
509 // If the prospective friend is not online, he'll get the message upon login. 567 // If the prospective friend is not online, he'll get the message upon login.
510 } 568 }
511 569
570 protected virtual string GetFriendshipRequesterName(UUID agentID)
571 {
572 UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
573 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
574 }
575
512 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) 576 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
513 { 577 {
514 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID); 578 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
515 579
516 FriendsService.StoreFriend(agentID, friendID.ToString(), 1); 580 StoreFriendships(agentID, friendID);
517 FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
518 581
519 ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>(); 582 ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
520 if (ccm != null) 583 if (ccm != null)
@@ -523,7 +586,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
523 } 586 }
524 587
525 // Update the local cache 588 // Update the local cache
526 UpdateFriendsCache(agentID); 589 RefetchFriends(client);
527 590
528 // 591 //
529 // Notify the friend 592 // Notify the friend
@@ -554,8 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
554 { 617 {
555 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); 618 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
556 619
557 FriendsService.Delete(agentID, friendID.ToString()); 620 DeleteFriendship(agentID, friendID);
558 FriendsService.Delete(friendID, agentID.ToString());
559 621
560 // 622 //
561 // Notify the friend 623 // Notify the friend
@@ -582,11 +644,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
582 644
583 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) 645 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
584 { 646 {
585 FriendsService.Delete(agentID, exfriendID.ToString()); 647 if (!DeleteFriendship(agentID, exfriendID))
586 FriendsService.Delete(exfriendID, agentID.ToString()); 648 client.SendAlertMessage("Unable to terminate friendship on this sim.");
587 649
588 // Update local cache 650 // Update local cache
589 UpdateFriendsCache(agentID); 651 RefetchFriends(client);
590 652
591 client.SendTerminateFriend(exfriendID); 653 client.SendTerminateFriend(exfriendID);
592 654
@@ -612,23 +674,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
612 674
613 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) 675 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
614 { 676 {
677 m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
678
615 FriendInfo[] friends = GetFriends(remoteClient.AgentId); 679 FriendInfo[] friends = GetFriends(remoteClient.AgentId);
616 if (friends.Length == 0) 680 if (friends.Length == 0)
681 {
617 return; 682 return;
683 }
618 684
619 m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
620 // Let's find the friend in this user's friend list 685 // Let's find the friend in this user's friend list
621 FriendInfo friend = null; 686 FriendInfo friend = GetFriend(friends, target);
622 foreach (FriendInfo fi in friends)
623 {
624 if (fi.Friend == target.ToString())
625 friend = fi;
626 }
627 687
628 if (friend != null) // Found it 688 if (friend != null) // Found it
629 { 689 {
630 // Store it on the DB 690 // Store it on the DB
631 FriendsService.StoreFriend(requester, target.ToString(), rights); 691 if (!StoreRights(requester, target, rights))
692 {
693 remoteClient.SendAlertMessage("Unable to grant rights.");
694 return;
695 }
632 696
633 // Store it in the local cache 697 // Store it in the local cache
634 int myFlags = friend.MyFlags; 698 int myFlags = friend.MyFlags;
@@ -658,6 +722,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
658 } 722 }
659 } 723 }
660 } 724 }
725 else
726 m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
727 }
728
729 protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
730 {
731 foreach (FriendInfo fi in friends)
732 {
733 if (fi.Friend == friendID.ToString())
734 return fi;
735 }
736 return null;
661 } 737 }
662 738
663 #region Local 739 #region Local
@@ -693,7 +769,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
693 769
694 770
695 // Update the local cache 771 // Update the local cache
696 UpdateFriendsCache(friendID); 772 RefetchFriends(friendClient);
697 773
698 // we're done 774 // we're done
699 return true; 775 return true;
@@ -726,7 +802,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
726 // the friend in this sim as root agent 802 // the friend in this sim as root agent
727 friendClient.SendTerminateFriend(exfriendID); 803 friendClient.SendTerminateFriend(exfriendID);
728 // update local cache 804 // update local cache
729 UpdateFriendsCache(exfriendID); 805 RefetchFriends(friendClient);
730 // we're done 806 // we're done
731 return true; 807 return true;
732 } 808 }
@@ -756,15 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
756 } 832 }
757 833
758 // Update local cache 834 // Update local cache
759 lock (m_Friends) 835 UpdateLocalCache(userID, friendID, rights);
760 {
761 FriendInfo[] friends = GetFriends(friendID);
762 foreach (FriendInfo finfo in friends)
763 {
764 if (finfo.Friend == userID.ToString())
765 finfo.TheirFlags = rights;
766 }
767 }
768 836
769 return true; 837 return true;
770 } 838 }
@@ -775,10 +843,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
775 843
776 public bool LocalStatusNotification(UUID userID, UUID friendID, bool online) 844 public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
777 { 845 {
846 m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
778 IClientAPI friendClient = LocateClientObject(friendID); 847 IClientAPI friendClient = LocateClientObject(friendID);
779 if (friendClient != null) 848 if (friendClient != null)
780 { 849 {
781 //m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
782 // the friend in this sim as root agent 850 // the friend in this sim as root agent
783 if (online) 851 if (online)
784 friendClient.SendAgentOnline(new UUID[] { userID }); 852 friendClient.SendAgentOnline(new UUID[] { userID });
@@ -793,7 +861,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
793 861
794 #endregion 862 #endregion
795 863
796 private FriendInfo[] GetFriends(UUID agentID) 864 #region Get / Set friends in several flavours
865 /// <summary>
866 /// Get friends from local cache only
867 /// </summary>
868 /// <param name="agentID"></param>
869 /// <returns></returns>
870 protected FriendInfo[] GetFriends(UUID agentID)
797 { 871 {
798 UserFriendData friendsData; 872 UserFriendData friendsData;
799 873
@@ -806,14 +880,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
806 return EMPTY_FRIENDS; 880 return EMPTY_FRIENDS;
807 } 881 }
808 882
809 private void UpdateFriendsCache(UUID agentID) 883 /// <summary>
884 /// Update loca cache only
885 /// </summary>
886 /// <param name="userID"></param>
887 /// <param name="friendID"></param>
888 /// <param name="rights"></param>
889 protected void UpdateLocalCache(UUID userID, UUID friendID, int rights)
890 {
891 // Update local cache
892 lock (m_Friends)
893 {
894 FriendInfo[] friends = GetFriends(friendID);
895 FriendInfo finfo = GetFriend(friends, userID);
896 finfo.TheirFlags = rights;
897 }
898 }
899
900 protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
901 {
902 return FriendsService.GetFriends(client.AgentId);
903 }
904
905 private void RefetchFriends(IClientAPI client)
810 { 906 {
907 UUID agentID = client.AgentId;
811 lock (m_Friends) 908 lock (m_Friends)
812 { 909 {
813 UserFriendData friendsData; 910 UserFriendData friendsData;
814 if (m_Friends.TryGetValue(agentID, out friendsData)) 911 if (m_Friends.TryGetValue(agentID, out friendsData))
815 friendsData.Friends = FriendsService.GetFriends(agentID); 912 friendsData.Friends = GetFriendsFromService(client);
816 } 913 }
817 } 914 }
915
916 protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
917 {
918 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
919 return true;
920 }
921
922 protected virtual void StoreBackwards(UUID friendID, UUID agentID)
923 {
924 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
925 }
926
927 protected virtual void StoreFriendships(UUID agentID, UUID friendID)
928 {
929 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
930 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
931 }
932
933 protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
934 {
935 FriendsService.Delete(agentID, exfriendID.ToString());
936 FriendsService.Delete(exfriendID, agentID.ToString());
937 return true;
938 }
939
940 #endregion
818 } 941 }
819} 942}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
new file mode 100644
index 0000000..b9d6719
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -0,0 +1,628 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Nwc.XmlRpc;
35using Mono.Addins;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.Connectors.Hypergrid;
42using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
43using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
44using GridRegion = OpenSim.Services.Interfaces.GridRegion;
45
46namespace OpenSim.Region.CoreModules.Avatar.Friends
47{
48 public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 #region ISharedRegionModule
53 public override string Name
54 {
55 get { return "HGFriendsModule"; }
56 }
57
58 public override void AddRegion(Scene scene)
59 {
60 if (!m_Enabled)
61 return;
62
63 base.AddRegion(scene);
64 scene.RegisterModuleInterface<IFriendsSimConnector>(this);
65 }
66
67 #endregion
68
69 #region IFriendsSimConnector
70
71 /// <summary>
72 /// Notify the user that the friend's status changed
73 /// </summary>
74 /// <param name="userID">user to be notified</param>
75 /// <param name="friendID">friend whose status changed</param>
76 /// <param name="online">status</param>
77 /// <returns></returns>
78 public bool StatusNotify(UUID friendID, UUID userID, bool online)
79 {
80 return LocalStatusNotification(friendID, userID, online);
81 }
82
83 #endregion
84
85 protected override bool FetchFriendslist(IClientAPI client)
86 {
87 if (base.FetchFriendslist(client))
88 {
89 UUID agentID = client.AgentId;
90 // we do this only for the root agent
91 if (m_Friends[agentID].Refcount == 1)
92 {
93 // We need to preload the user management cache with the names
94 // of foreign friends, just like we do with SOPs' creators
95 foreach (FriendInfo finfo in m_Friends[agentID].Friends)
96 {
97 if (finfo.TheirFlags != -1)
98 {
99 UUID id;
100 if (!UUID.TryParse(finfo.Friend, out id))
101 {
102 string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
103 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
104 {
105 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
106 uMan.AddUser(id, url + ";" + first + " " + last);
107 }
108 }
109 }
110 }
111 return true;
112 }
113 }
114 return false;
115 }
116
117 public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
118 {
119 if (base.SendFriendsOnlineIfNeeded(client))
120 {
121 AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
122 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
123 {
124 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
125 if (account == null) // foreign
126 {
127 FriendInfo[] friends = GetFriends(client.AgentId);
128 foreach (FriendInfo f in friends)
129 {
130 client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
131 }
132 }
133 }
134 }
135 return false;
136 }
137
138 protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
139 {
140 List<string> fList = new List<string>();
141 foreach (string s in friendList)
142 fList.Add(s.Substring(0, 36));
143
144 PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
145 foreach (PresenceInfo pi in presence)
146 {
147 UUID presenceID;
148 if (UUID.TryParse(pi.UserID, out presenceID))
149 online.Add(presenceID);
150 }
151 }
152
153 //protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
154 //{
155 // // Let's single out the UUIs
156 // List<string> localFriends = new List<string>();
157 // List<string> foreignFriends = new List<string>();
158 // string tmp = string.Empty;
159
160 // foreach (string s in friendList)
161 // {
162 // UUID id;
163 // if (UUID.TryParse(s, out id))
164 // localFriends.Add(s);
165 // else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
166 // {
167 // foreignFriends.Add(s);
168 // // add it here too, who knows maybe the foreign friends happens to be on this grid
169 // localFriends.Add(id.ToString());
170 // }
171 // }
172
173 // // OK, see who's present on this grid
174 // List<string> toBeRemoved = new List<string>();
175 // PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
176 // foreach (PresenceInfo pi in presence)
177 // {
178 // UUID presenceID;
179 // if (UUID.TryParse(pi.UserID, out presenceID))
180 // {
181 // online.Add(presenceID);
182 // foreach (string s in foreignFriends)
183 // if (s.StartsWith(pi.UserID))
184 // toBeRemoved.Add(s);
185 // }
186 // }
187
188 // foreach (string s in toBeRemoved)
189 // foreignFriends.Remove(s);
190
191 // // OK, let's send this up the stack, and leave a closure here
192 // // collecting online friends in other grids
193 // Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
194
195 //}
196
197 private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
198 {
199 // let's divide the friends on a per-domain basis
200 Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
201 foreach (string friend in foreignFriends)
202 {
203 UUID friendID;
204 if (!UUID.TryParse(friend, out friendID))
205 {
206 // it's a foreign friend
207 string url = string.Empty, tmp = string.Empty;
208 if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
209 {
210 if (!friendsPerDomain.ContainsKey(url))
211 friendsPerDomain[url] = new List<string>();
212 friendsPerDomain[url].Add(friend);
213 }
214 }
215 }
216
217 // Now, call those worlds
218
219 foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
220 {
221 List<string> ids = new List<string>();
222 foreach (string f in kvp.Value)
223 ids.Add(f);
224 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
225 List<UUID> online = uConn.GetOnlineFriends(userID, ids);
226 // Finally send the notifications to the user
227 // this whole process may take a while, so let's check at every
228 // iteration that the user is still here
229 IClientAPI client = LocateClientObject(userID);
230 if (client != null)
231 client.SendAgentOnline(online.ToArray());
232 else
233 break;
234 }
235
236 }
237
238 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
239 {
240 // First, let's divide the friends on a per-domain basis
241 Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
242 foreach (FriendInfo friend in friendList)
243 {
244 UUID friendID;
245 if (UUID.TryParse(friend.Friend, out friendID))
246 {
247 if (!friendsPerDomain.ContainsKey("local"))
248 friendsPerDomain["local"] = new List<FriendInfo>();
249 friendsPerDomain["local"].Add(friend);
250 }
251 else
252 {
253 // it's a foreign friend
254 string url = string.Empty, tmp = string.Empty;
255 if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
256 {
257 // Let's try our luck in the local sim. Who knows, maybe it's here
258 if (LocalStatusNotification(userID, friendID, online))
259 continue;
260
261 if (!friendsPerDomain.ContainsKey(url))
262 friendsPerDomain[url] = new List<FriendInfo>();
263 friendsPerDomain[url].Add(friend);
264 }
265 }
266 }
267
268 // For the local friends, just call the base method
269 // Let's do this first of all
270 if (friendsPerDomain.ContainsKey("local"))
271 base.StatusNotify(friendsPerDomain["local"], userID, online);
272
273 foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
274 {
275 if (kvp.Key != "local")
276 {
277 // For the others, call the user agent service
278 List<string> ids = new List<string>();
279 foreach (FriendInfo f in kvp.Value)
280 ids.Add(f.Friend);
281 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
282 List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
283 // need to debug this here
284 if (online)
285 {
286 IClientAPI client = LocateClientObject(userID);
287 if (client != null)
288 client.SendAgentOnline(friendsOnline.ToArray());
289 }
290 }
291 }
292 }
293
294 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
295 {
296 first = "Unknown"; last = "User";
297 if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
298 return true;
299
300 // fid is not a UUID...
301 string url = string.Empty, tmp = string.Empty;
302 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
303 {
304 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
305 userMan.AddUser(agentID, url + ";" + first + " " + last);
306
307 try // our best
308 {
309 string[] parts = userMan.GetUserName(agentID).Split();
310 first = parts[0];
311 last = parts[1];
312 }
313 catch { }
314 return true;
315 }
316 return false;
317 }
318
319 protected override string GetFriendshipRequesterName(UUID agentID)
320 {
321 // For the time being we assume that HG friendship requests can only happen
322 // when avies are on the same region.
323 IClientAPI client = LocateClientObject(agentID);
324 if (client != null)
325 return client.FirstName + " " + client.LastName;
326 else
327 return base.GetFriendshipRequesterName(agentID);
328 }
329
330 protected override string FriendshipMessage(string friendID)
331 {
332 UUID id;
333 if (UUID.TryParse(friendID, out id))
334 return base.FriendshipMessage(friendID);
335
336 return "Please confirm this friendship you made while you were away.";
337 }
338
339 protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
340 {
341 foreach (FriendInfo fi in friends)
342 {
343 if (fi.Friend.StartsWith(friendID.ToString()))
344 return fi;
345 }
346 return null;
347 }
348
349
350 protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
351 {
352 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
353 if (account1 != null)
354 return base.GetFriendsFromService(client);
355
356 FriendInfo[] finfos = new FriendInfo[0];
357 // Foreigner
358 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
359 if (agentClientCircuit != null)
360 {
361 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
362
363 finfos = FriendsService.GetFriends(agentUUI);
364 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
365 }
366 return finfos;
367 }
368
369 protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
370 {
371 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
372 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
373 // Are they both local users?
374 if (account1 != null && account2 != null)
375 {
376 // local grid users
377 return base.StoreRights(agentID, friendID, rights);
378 }
379
380 if (account1 != null) // agent is local, friend is foreigner
381 {
382 FriendInfo[] finfos = GetFriends(agentID);
383 FriendInfo finfo = GetFriend(finfos, friendID);
384 if (finfo != null)
385 {
386 FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
387 return true;
388 }
389 }
390
391 if (account2 != null) // agent is foreigner, friend is local
392 {
393 string agentUUI = GetUUI(friendID, agentID);
394 if (agentUUI != string.Empty)
395 {
396 FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
397 return true;
398 }
399 }
400
401 return false;
402
403 }
404
405 protected override void StoreBackwards(UUID friendID, UUID agentID)
406 {
407 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
408 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
409 // Are they both local users?
410 if (account1 != null && account2 != null)
411 {
412 // local grid users
413 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
414 base.StoreBackwards(friendID, agentID);
415 return;
416 }
417
418 // no provision for this temporary friendship state
419 //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
420 }
421
422 protected override void StoreFriendships(UUID agentID, UUID friendID)
423 {
424 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
425 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
426 // Are they both local users?
427 if (agentAccount != null && friendAccount != null)
428 {
429 // local grid users
430 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
431 base.StoreFriendships(agentID, friendID);
432 return;
433 }
434
435 // ok, at least one of them is foreigner, let's get their data
436 IClientAPI agentClient = LocateClientObject(agentID);
437 IClientAPI friendClient = LocateClientObject(friendID);
438 AgentCircuitData agentClientCircuit = null;
439 AgentCircuitData friendClientCircuit = null;
440 string agentUUI = string.Empty;
441 string friendUUI = string.Empty;
442 string agentFriendService = string.Empty;
443 string friendFriendService = string.Empty;
444
445 if (agentClient != null)
446 {
447 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
448 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
449 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
450 }
451 if (friendClient != null)
452 {
453 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
454 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
455 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
456 }
457
458 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
459 agentUUI, friendUUI, agentFriendService, friendFriendService);
460
461 // Generate a random 8-character hex number that will sign this friendship
462 string secret = UUID.Random().ToString().Substring(0, 8);
463
464 if (agentAccount != null) // agent is local, 'friend' is foreigner
465 {
466 // This may happen when the agent returned home, in which case the friend is not there
467 // We need to look for its information in the friends list itself
468 bool confirming = false;
469 if (friendUUI == string.Empty)
470 {
471 FriendInfo[] finfos = GetFriends(agentID);
472 foreach (FriendInfo finfo in finfos)
473 {
474 if (finfo.TheirFlags == -1)
475 {
476 if (finfo.Friend.StartsWith(friendID.ToString()))
477 {
478 friendUUI = finfo.Friend;
479 confirming = true;
480 }
481 }
482 }
483 }
484
485 // If it's confirming the friendship, we already have the full friendUUI with the secret
486 string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
487
488 // store in the local friends service a reference to the foreign friend
489 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
490 // and also the converse
491 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
492
493 if (!confirming && friendClientCircuit != null)
494 {
495 // store in the foreign friends service a reference to the local agent
496 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
497 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
498 }
499 }
500 else if (friendAccount != null) // 'friend' is local, agent is foreigner
501 {
502 // store in the local friends service a reference to the foreign agent
503 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
504 // and also the converse
505 FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
506
507 if (agentClientCircuit != null)
508 {
509 // store in the foreign friends service a reference to the local agent
510 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
511 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
512 }
513 }
514 else // They're both foreigners!
515 {
516 HGFriendsServicesConnector friendsConn;
517 if (agentClientCircuit != null)
518 {
519 friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
520 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
521 }
522 if (friendClientCircuit != null)
523 {
524 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
525 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
526 }
527 }
528 // my brain hurts now
529 }
530
531 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
532 {
533 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
534 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
535 // Are they both local users?
536 if (agentAccount != null && friendAccount != null)
537 {
538 // local grid users
539 return base.DeleteFriendship(agentID, exfriendID);
540 }
541
542 // ok, at least one of them is foreigner, let's get their data
543 string agentUUI = string.Empty;
544 string friendUUI = string.Empty;
545
546 if (agentAccount != null) // agent is local, 'friend' is foreigner
547 {
548 // We need to look for its information in the friends list itself
549 FriendInfo[] finfos = GetFriends(agentID);
550 FriendInfo finfo = GetFriend(finfos, exfriendID);
551 if (finfo != null)
552 {
553 friendUUI = finfo.Friend;
554
555 // delete in the local friends service the reference to the foreign friend
556 FriendsService.Delete(agentID, friendUUI);
557 // and also the converse
558 FriendsService.Delete(friendUUI, agentID.ToString());
559
560 // notify the exfriend's service
561 Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
562
563 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
564 return true;
565 }
566 }
567 else if (friendAccount != null) // agent is foreigner, 'friend' is local
568 {
569 agentUUI = GetUUI(exfriendID, agentID);
570
571 if (agentUUI != string.Empty)
572 {
573 // delete in the local friends service the reference to the foreign agent
574 FriendsService.Delete(exfriendID, agentUUI);
575 // and also the converse
576 FriendsService.Delete(agentUUI, exfriendID.ToString());
577
578 // notify the agent's service?
579 Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
580
581 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
582 return true;
583 }
584 }
585 //else They're both foreigners! Can't handle this
586
587 return false;
588 }
589
590 private string GetUUI(UUID localUser, UUID foreignUser)
591 {
592 // Let's see if the user is here by any chance
593 FriendInfo[] finfos = GetFriends(localUser);
594 if (finfos != EMPTY_FRIENDS) // friend is here, cool
595 {
596 FriendInfo finfo = GetFriend(finfos, foreignUser);
597 if (finfo != null)
598 {
599 return finfo.Friend;
600 }
601 }
602 else // user is not currently on this sim, need to get from the service
603 {
604 finfos = FriendsService.GetFriends(localUser);
605 foreach (FriendInfo finfo in finfos)
606 {
607 if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
608 {
609 return finfo.Friend;
610 }
611 }
612 }
613 return string.Empty;
614 }
615
616 private void Delete(UUID foreignUser, UUID localUser, string uui)
617 {
618 UUID id;
619 string url = string.Empty, secret = string.Empty, tmp = string.Empty;
620 if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
621 {
622 m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
623 HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
624 friendConn.DeleteFriendship(foreignUser, localUser, secret);
625 }
626 }
627 }
628}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
new file mode 100644
index 0000000..7753c25
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
@@ -0,0 +1,350 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Nwc.XmlRpc;
35using Mono.Addins;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
42using OpenSim.Services.Interfaces;
43using OpenSim.Services.Connectors.InstantMessage;
44using OpenSim.Services.Connectors.Hypergrid;
45using OpenSim.Server.Handlers.Hypergrid;
46
47namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
50 public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector
51 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 protected bool m_Enabled = false;
55 protected List<Scene> m_Scenes = new List<Scene>();
56
57 protected IInstantMessage m_IMService;
58 protected Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
59
60 public event UndeliveredMessage OnUndeliveredMessage;
61
62 IUserManagement m_uMan;
63 IUserManagement UserManagementModule
64 {
65 get
66 {
67 if (m_uMan == null)
68 m_uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
69 return m_uMan;
70 }
71 }
72
73 public virtual void Initialise(IConfigSource config)
74 {
75 IConfig cnf = config.Configs["Messaging"];
76 if (cnf != null && cnf.GetString(
77 "MessageTransferModule", "MessageTransferModule") != Name)
78 {
79 m_log.Debug("[HG MESSAGE TRANSFER]: Disabled by configuration");
80 return;
81 }
82
83 InstantMessageServerConnector imServer = new InstantMessageServerConnector(config, MainServer.Instance, this);
84 m_IMService = imServer.GetService();
85 m_Enabled = true;
86 }
87
88 public virtual void AddRegion(Scene scene)
89 {
90 if (!m_Enabled)
91 return;
92
93 lock (m_Scenes)
94 {
95 m_log.DebugFormat("[HG MESSAGE TRANSFER]: Message transfer module {0} active", Name);
96 scene.RegisterModuleInterface<IMessageTransferModule>(this);
97 m_Scenes.Add(scene);
98 }
99 }
100
101 public virtual void PostInitialise()
102 {
103 if (!m_Enabled)
104 return;
105
106 }
107
108 public virtual void RegionLoaded(Scene scene)
109 {
110 }
111
112 public virtual void RemoveRegion(Scene scene)
113 {
114 if (!m_Enabled)
115 return;
116
117 lock (m_Scenes)
118 {
119 m_Scenes.Remove(scene);
120 }
121 }
122
123 public virtual void Close()
124 {
125 }
126
127 public virtual string Name
128 {
129 get { return "HGMessageTransferModule"; }
130 }
131
132 public virtual Type ReplaceableInterface
133 {
134 get { return null; }
135 }
136
137 public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
138 {
139 UUID toAgentID = new UUID(im.toAgentID);
140
141 // Try root avatar only first
142 foreach (Scene scene in m_Scenes)
143 {
144 if (scene.Entities.ContainsKey(toAgentID) &&
145 scene.Entities[toAgentID] is ScenePresence)
146 {
147// m_log.DebugFormat(
148// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
149// toAgentID.ToString(), scene.RegionInfo.RegionName);
150
151 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
152 if (!user.IsChildAgent)
153 {
154 // Local message
155// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
156 user.ControllingClient.SendInstantMessage(im);
157
158 // Message sent
159 result(true);
160 return;
161 }
162 }
163 }
164
165 // try child avatar second
166 foreach (Scene scene in m_Scenes)
167 {
168// m_log.DebugFormat(
169// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
170
171 if (scene.Entities.ContainsKey(toAgentID) &&
172 scene.Entities[toAgentID] is ScenePresence)
173 {
174 // Local message
175 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
176
177// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
178 user.ControllingClient.SendInstantMessage(im);
179
180 // Message sent
181 result(true);
182 return;
183 }
184 }
185
186// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
187 // Is the user a local user?
188 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
189 string url = string.Empty;
190 bool foreigner = false;
191 if (account == null) // foreign user
192 {
193 url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI");
194 foreigner = true;
195 }
196
197 Util.FireAndForget(delegate
198 {
199 bool success = false;
200 if (foreigner && url == string.Empty) // we don't know about this user
201 {
202 string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID);
203 m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
204 if (recipientUUI != string.Empty)
205 {
206 UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty;
207 if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret))
208 {
209 success = m_IMService.OutgoingInstantMessage(im, u, true);
210 if (success)
211 UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last);
212 }
213 }
214 }
215 else
216 success = m_IMService.OutgoingInstantMessage(im, url, foreigner);
217
218 if (!success && !foreigner)
219 HandleUndeliveredMessage(im, result);
220 else
221 result(success);
222 });
223
224 return;
225 }
226
227 protected bool SendIMToScene(GridInstantMessage gim, UUID toAgentID)
228 {
229 bool successful = false;
230 foreach (Scene scene in m_Scenes)
231 {
232 if (scene.Entities.ContainsKey(toAgentID) &&
233 scene.Entities[toAgentID] is ScenePresence)
234 {
235 ScenePresence user =
236 (ScenePresence)scene.Entities[toAgentID];
237
238 if (!user.IsChildAgent)
239 {
240 scene.EventManager.TriggerIncomingInstantMessage(gim);
241 successful = true;
242 }
243 }
244 }
245 if (!successful)
246 {
247 // If the message can't be delivered to an agent, it
248 // is likely to be a group IM. On a group IM, the
249 // imSessionID = toAgentID = group id. Raise the
250 // unhandled IM event to give the groups module
251 // a chance to pick it up. We raise that in a random
252 // scene, since the groups module is shared.
253 //
254 m_Scenes[0].EventManager.TriggerUnhandledInstantMessage(gim);
255 }
256
257 return successful;
258 }
259
260 protected void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
261 {
262 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
263
264 // If this event has handlers, then an IM from an agent will be
265 // considered delivered. This will suppress the error message.
266 //
267 if (handlerUndeliveredMessage != null)
268 {
269 handlerUndeliveredMessage(im);
270 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
271 result(true);
272 else
273 result(false);
274 return;
275 }
276
277 //m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
278 result(false);
279 }
280
281 private string TryGetRecipientUUI(UUID fromAgent, UUID toAgent)
282 {
283 // Let's call back the fromAgent's user agent service
284 // Maybe that service knows about the toAgent
285 IClientAPI client = LocateClientObject(fromAgent);
286 if (client != null)
287 {
288 AgentCircuitData circuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.AgentId);
289 if (circuit != null)
290 {
291 if (circuit.ServiceURLs.ContainsKey("HomeURI"))
292 {
293 string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
294 m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
295 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
296 return uasConn.GetUUI(fromAgent, toAgent);
297 }
298 }
299 }
300
301 return string.Empty;
302 }
303
304
305 /// <summary>
306 /// Find the scene for an agent
307 /// </summary>
308 private Scene GetClientScene(UUID agentId)
309 {
310 lock (m_Scenes)
311 {
312 foreach (Scene scene in m_Scenes)
313 {
314 ScenePresence presence = scene.GetScenePresence(agentId);
315 if (presence != null && !presence.IsChildAgent)
316 return scene;
317 }
318 }
319
320 return null;
321 }
322
323 /// <summary>
324 /// Find the client for a ID
325 /// </summary>
326 public IClientAPI LocateClientObject(UUID agentID)
327 {
328 Scene scene = GetClientScene(agentID);
329 if (scene != null)
330 {
331 ScenePresence presence = scene.GetScenePresence(agentID);
332 if (presence != null)
333 return presence.ControllingClient;
334 }
335
336 return null;
337 }
338
339 #region IInstantMessageSimConnector
340 public bool SendInstantMessage(GridInstantMessage im)
341 {
342 //m_log.DebugFormat("[XXX] Hook SendInstantMessage {0}", im.message);
343 UUID agentID = new UUID(im.toAgentID);
344 return SendIMToScene(im, agentID);
345 }
346 #endregion
347
348
349 }
350}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index 47e34dc..0d90a15 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -149,14 +149,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
149 149
150 /// <summary> 150 /// <summary>
151 /// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder. 151 /// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder.
152 /// 152 /// </summary>
153 /// <remarks>
153 /// This method does not handle paths that contain multiple delimitors 154 /// This method does not handle paths that contain multiple delimitors
154 /// 155 ///
155 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some 156 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
156 /// XPath like expression 157 /// XPath like expression
157 /// 158 ///
158 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 159 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
159 /// </summary> 160 /// </remarks>
160 /// 161 ///
161 /// <param name="inventoryService"> 162 /// <param name="inventoryService">
162 /// Inventory service to query 163 /// Inventory service to query
@@ -178,32 +179,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
178 179
179 return FindItemByPath(inventoryService, rootFolder, path); 180 return FindItemByPath(inventoryService, rootFolder, path);
180 } 181 }
181 182
182 /// <summary> 183 /// <summary>
183 /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. 184 /// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
184 /// 185 /// </summary>
185 /// This method does not handle paths that contain multiple delimitors 186 /// <remarks>
187 /// This method does not handle paths that contain multiple delimiters
186 /// 188 ///
187 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some 189 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
188 /// XPath like expression 190 /// XPath like expression
189 /// 191 ///
190 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 192 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
191 /// </summary> 193 /// </remarks>
192 /// 194 ///
193 /// <param name="inventoryService"> 195 /// <param name="inventoryService">Inventory service to query</param>
194 /// Inventory service to query 196 /// <param name="startFolder">The folder from which the path starts</param>
195 /// </param> 197 /// <param name="path">The path to the required item.</param>
196 /// <param name="startFolder">
197 /// The folder from which the path starts
198 /// </param>
199 /// <param name="path">
200 /// <param name="path">
201 /// The path to the required item.
202 /// </param>
203 /// <returns>null if the item is not found</returns> 198 /// <returns>null if the item is not found</returns>
204 public static InventoryItemBase FindItemByPath( 199 public static InventoryItemBase FindItemByPath(
205 IInventoryService inventoryService, InventoryFolderBase startFolder, string path) 200 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
206 { 201 {
202 List<InventoryItemBase> foundItems = FindItemsByPath(inventoryService, startFolder, path);
203
204 if (foundItems.Count != 0)
205 return foundItems[0];
206 else
207 return null;
208 }
209
210 public static List<InventoryItemBase> FindItemsByPath(
211 IInventoryService inventoryService, UUID userId, string path)
212 {
213 InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
214
215 if (null == rootFolder)
216 return new List<InventoryItemBase>();
217
218 return FindItemsByPath(inventoryService, rootFolder, path);
219 }
220
221 /// <summary>
222 /// Find items that match a given PATH_DELIMITOR delimited path starting from this folder.
223 /// </summary>
224 /// <remarks>
225 /// This method does not handle paths that contain multiple delimiters
226 ///
227 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
228 /// XPath like expression
229 ///
230 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
231 /// </remarks>
232 ///
233 /// <param name="inventoryService">Inventory service to query</param>
234 /// <param name="startFolder">The folder from which the path starts</param>
235 /// <param name="path">The path to the required item.</param>
236 /// <returns>The items that were found with this path. An empty list if no items were found.</returns>
237 public static List<InventoryItemBase> FindItemsByPath(
238 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
239 {
240 List<InventoryItemBase> foundItems = new List<InventoryItemBase>();
241
207 // If the path isn't just / then trim any starting extraneous slashes 242 // If the path isn't just / then trim any starting extraneous slashes
208 path = path.TrimStart(new char[] { PATH_DELIMITER }); 243 path = path.TrimStart(new char[] { PATH_DELIMITER });
209 244
@@ -215,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
215 if (components.Length == 1) 250 if (components.Length == 1)
216 { 251 {
217// m_log.DebugFormat( 252// m_log.DebugFormat(
218// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}", 253// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
219// components[0], startFolder.Name, startFolder.ID); 254// components[0], startFolder.Name, startFolder.ID);
220 255
221 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); 256 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
222 257
223// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count); 258// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
224 259
225 foreach (InventoryItemBase item in items) 260 foreach (InventoryItemBase item in items)
@@ -227,24 +262,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
227// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID); 262// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
228 263
229 if (item.Name == components[0]) 264 if (item.Name == components[0])
230 return item; 265 foundItems.Add(item);
231 } 266 }
232 } 267 }
233 else 268 else
234 { 269 {
235// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]); 270// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
236 271
237 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 272 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
238 273
239 foreach (InventoryFolderBase folder in contents.Folders) 274 foreach (InventoryFolderBase folder in contents.Folders)
240 { 275 {
241 if (folder.Name == components[0]) 276 if (folder.Name == components[0])
242 return FindItemByPath(inventoryService, folder, components[1]); 277 foundItems.AddRange(FindItemsByPath(inventoryService, folder, components[1]));
243 } 278 }
244 } 279 }
245 280
246 // We didn't find an item or intermediate folder with the given name 281 return foundItems;
247 return null;
248 } 282 }
249 283
250 /// <summary> 284 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index e043caa..93657a8 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -154,7 +154,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
154 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); 154 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
155 m_archiveWriter.WriteFile(filename, serialization); 155 m_archiveWriter.WriteFile(filename, serialization);
156 156
157 if (SaveAssets) 157 AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
158
159 // Don't chase down link asset items as they actually point to their target item IDs rather than an asset
160 if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
158 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); 161 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
159 } 162 }
160 163
@@ -246,10 +249,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
246 249
247 // The path may point to an item instead 250 // The path may point to an item instead
248 if (inventoryFolder == null) 251 if (inventoryFolder == null)
249 {
250 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); 252 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
251 //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
252 }
253 253
254 if (null == inventoryFolder && null == inventoryItem) 254 if (null == inventoryFolder && null == inventoryItem)
255 { 255 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
new file mode 100644
index 0000000..c82cfd2
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -0,0 +1,244 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using Mono.Addins;
35
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Connectors.Hypergrid;
40
41using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42
43namespace OpenSim.Region.CoreModules.Avatar.Lure
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
46 public class HGLureModule : ISharedRegionModule
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(
49 MethodBase.GetCurrentMethod().DeclaringType);
50
51 private readonly List<Scene> m_scenes = new List<Scene>();
52
53 private IMessageTransferModule m_TransferModule = null;
54 private bool m_Enabled = false;
55
56 private string m_ThisGridURL;
57
58 private ExpiringCache<UUID, GridInstantMessage> m_PendingLures = new ExpiringCache<UUID, GridInstantMessage>();
59
60 public void Initialise(IConfigSource config)
61 {
62 if (config.Configs["Messaging"] != null)
63 {
64 if (config.Configs["Messaging"].GetString("LureModule", string.Empty) == "HGLureModule")
65 {
66 m_Enabled = true;
67
68 m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty);
69 m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
70 }
71 }
72 }
73
74 public void AddRegion(Scene scene)
75 {
76 if (!m_Enabled)
77 return;
78
79 lock (m_scenes)
80 {
81 m_scenes.Add(scene);
82 scene.EventManager.OnIncomingInstantMessage += OnIncomingInstantMessage;
83 scene.EventManager.OnNewClient += OnNewClient;
84 }
85 }
86
87 public void RegionLoaded(Scene scene)
88 {
89 if (!m_Enabled)
90 return;
91
92 if (m_TransferModule == null)
93 {
94 m_TransferModule =
95 scene.RequestModuleInterface<IMessageTransferModule>();
96
97 if (m_TransferModule == null)
98 {
99 m_log.Error("[LURE MODULE]: No message transfer module, lures will not work!");
100
101 m_Enabled = false;
102 m_scenes.Clear();
103 scene.EventManager.OnNewClient -= OnNewClient;
104 scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
105 }
106 }
107
108 }
109
110 public void RemoveRegion(Scene scene)
111 {
112 if (!m_Enabled)
113 return;
114
115 lock (m_scenes)
116 {
117 m_scenes.Remove(scene);
118 scene.EventManager.OnNewClient -= OnNewClient;
119 scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
120 }
121 }
122
123 void OnNewClient(IClientAPI client)
124 {
125 client.OnInstantMessage += OnInstantMessage;
126 client.OnStartLure += OnStartLure;
127 client.OnTeleportLureRequest += OnTeleportLureRequest;
128 }
129
130 public void PostInitialise()
131 {
132 }
133
134 public void Close()
135 {
136 }
137
138 public string Name
139 {
140 get { return "HGLureModule"; }
141 }
142
143 public Type ReplaceableInterface
144 {
145 get { return null; }
146 }
147
148 void OnInstantMessage(IClientAPI client, GridInstantMessage im)
149 {
150 }
151
152 void OnIncomingInstantMessage(GridInstantMessage im)
153 {
154 if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
155 {
156 UUID sessionID = new UUID(im.imSessionID);
157 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
158 m_PendingLures.Add(sessionID, im, 7200); // 2 hours
159
160 // Forward. We do this, because the IM module explicitly rejects
161 // IMs of this type
162 if (m_TransferModule != null)
163 m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
164
165 }
166 }
167
168 public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client)
169 {
170 if (!(client.Scene is Scene))
171 return;
172
173 Scene scene = (Scene)(client.Scene);
174 ScenePresence presence = scene.GetScenePresence(client.AgentId);
175
176 message += "@" + m_ThisGridURL;
177
178 m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
179
180 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
181 client.FirstName+" "+client.LastName, targetid,
182 (byte)InstantMessageDialog.RequestTeleport, false,
183 message, UUID.Random(), false, presence.AbsolutePosition,
184 new Byte[0]);
185 m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
186
187 if (m_TransferModule != null)
188 {
189 m_TransferModule.SendInstantMessage(m,
190 delegate(bool success) { });
191 }
192 }
193
194 public void OnTeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client)
195 {
196 if (!(client.Scene is Scene))
197 return;
198
199 Scene scene = (Scene)(client.Scene);
200
201 GridInstantMessage im = null;
202 if (m_PendingLures.TryGetValue(lureID, out im))
203 {
204 m_PendingLures.Remove(lureID);
205 Lure(client, teleportFlags, im);
206 }
207 else
208 m_log.DebugFormat("[HG LURE MODULE]: pending lure {0} not found", lureID);
209
210 }
211
212 private void Lure(IClientAPI client, uint teleportflags, GridInstantMessage im)
213 {
214 Scene scene = (Scene)(client.Scene);
215 GridRegion region = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID, new UUID(im.RegionID));
216 if (region != null)
217 scene.RequestTeleportLocation(client, region.RegionHandle, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags);
218 else // we don't have that region here. Check if it's HG
219 {
220 string[] parts = im.message.Split(new char[] { '@' });
221 if (parts.Length > 1)
222 {
223 string url = parts[parts.Length - 1]; // the last part
224 if (url.Trim(new char[] {'/'}) != m_ThisGridURL.Trim(new char[] {'/'}))
225 {
226 m_log.DebugFormat("[HG LURE MODULE]: Luring agent to grid {0} region {1} position {2}", url, im.RegionID, im.Position);
227 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
228 GridRegion gatekeeper = new GridRegion();
229 gatekeeper.ServerURI = url;
230 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID));
231 if (finalDestination != null)
232 {
233 ScenePresence sp = scene.GetScenePresence(client.AgentId);
234 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
235 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
236 if (transferMod != null && sp != null && eq != null)
237 transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq);
238 }
239 }
240 }
241 }
242 }
243 }
244}
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index a12b57a..dcfdf8f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -45,16 +45,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
45 private readonly List<Scene> m_scenes = new List<Scene>(); 45 private readonly List<Scene> m_scenes = new List<Scene>();
46 46
47 private IMessageTransferModule m_TransferModule = null; 47 private IMessageTransferModule m_TransferModule = null;
48 private bool m_Enabled = true; 48 private bool m_Enabled = false;
49 49
50 public void Initialise(IConfigSource config) 50 public void Initialise(IConfigSource config)
51 { 51 {
52 if (config.Configs["Messaging"] != null) 52 if (config.Configs["Messaging"] != null)
53 { 53 {
54 if (config.Configs["Messaging"].GetString( 54 if (config.Configs["Messaging"].GetString(
55 "LureModule", "LureModule") != 55 "LureModule", "LureModule") ==
56 "LureModule") 56 "LureModule")
57 m_Enabled = false; 57 {
58 m_Enabled = true;
59 m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
60 }
58 } 61 }
59 } 62 }
60 63
@@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
74 77
75 public void RegionLoaded(Scene scene) 78 public void RegionLoaded(Scene scene)
76 { 79 {
80 if (!m_Enabled)
81 return;
82
77 if (m_TransferModule == null) 83 if (m_TransferModule == null)
78 { 84 {
79 m_TransferModule = 85 m_TransferModule =
@@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
96 102
97 public void RemoveRegion(Scene scene) 103 public void RemoveRegion(Scene scene)
98 { 104 {
105 if (!m_Enabled)
106 return;
107
99 lock (m_scenes) 108 lock (m_scenes)
100 { 109 {
101 m_scenes.Remove(scene); 110 m_scenes.Remove(scene);
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
new file mode 100644
index 0000000..079e1b6
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
@@ -0,0 +1,173 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using System.Globalization;
31using System.Reflection;
32
33using OpenMetaverse;
34using log4net;
35using Nini.Config;
36using Mono.Addins;
37
38using OpenSim.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces;
42
43namespace OpenSim.Region.CoreModules.Avatar.Profile
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
46 public class BasicProfileModule : ISharedRegionModule
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 //
51 // Module vars
52 //
53 private List<Scene> m_Scenes = new List<Scene>();
54 private bool m_Enabled = false;
55
56 #region ISharedRegionModule
57
58 public void Initialise(IConfigSource config)
59 {
60 if (config.Configs["Profile"] != null)
61 {
62 if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule")
63 return;
64 }
65
66 m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled");
67 m_Enabled = true;
68
69 }
70
71 public void AddRegion(Scene scene)
72 {
73 if (!m_Enabled)
74 return;
75
76 lock (m_Scenes)
77 {
78 if (!m_Scenes.Contains(scene))
79 {
80 m_Scenes.Add(scene);
81 // Hook up events
82 scene.EventManager.OnNewClient += OnNewClient;
83 }
84 }
85 }
86
87 public void RegionLoaded(Scene scene)
88 {
89 if (!m_Enabled)
90 return;
91 }
92
93 public void RemoveRegion(Scene scene)
94 {
95 if (!m_Enabled)
96 return;
97
98 lock (m_Scenes)
99 {
100 m_Scenes.Remove(scene);
101 }
102 }
103
104 public void PostInitialise()
105 {
106 }
107
108 public void Close()
109 {
110 }
111
112 public string Name
113 {
114 get { return "BasicProfileModule"; }
115 }
116
117 public Type ReplaceableInterface
118 {
119 get { return null; }
120 }
121
122 #endregion
123
124 /// New Client Event Handler
125 private void OnNewClient(IClientAPI client)
126 {
127 //Profile
128 client.OnRequestAvatarProperties += RequestAvatarProperties;
129 }
130
131 public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
132 {
133 IScene s = remoteClient.Scene;
134 if (!(s is Scene))
135 return;
136
137 Scene scene = (Scene)s;
138
139 string profileUrl = String.Empty;
140 string aboutText = String.Empty;
141 string firstLifeAboutText = String.Empty;
142 UUID image = UUID.Zero;
143 UUID firstLifeImage = UUID.Zero;
144 UUID partner = UUID.Zero;
145 uint wantMask = 0;
146 string wantText = String.Empty;
147 uint skillsMask = 0;
148 string skillsText = String.Empty;
149 string languages = String.Empty;
150
151 Byte[] charterMember = Utils.StringToBytes("Avatar");
152
153 profileUrl = "No profile data";
154 aboutText = string.Empty;
155 firstLifeAboutText = string.Empty;
156 image = UUID.Zero;
157 firstLifeImage = UUID.Zero;
158 partner = UUID.Zero;
159
160 remoteClient.SendAvatarProperties(avatarID, aboutText,
161 Util.ToDateTime(0).ToString(
162 "M/d/yyyy", CultureInfo.InvariantCulture),
163 charterMember, firstLifeAboutText,
164 (uint)(0 & 0xff),
165 firstLifeImage, image, profileUrl, partner);
166
167 //Viewer expects interest data when it asks for properties.
168 remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
169 skillsMask, skillsText, languages);
170 }
171
172 }
173} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 1fb346e..02efcd8 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
52 52
53 protected bool m_Enabled = false; 53 protected bool m_Enabled = false;
54 protected Scene m_aScene; 54 protected Scene m_aScene;
55 protected List<Scene> m_Scenes = new List<Scene>();
55 protected List<UUID> m_agentsInTransit; 56 protected List<UUID> m_agentsInTransit;
56 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = 57 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
57 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); 58 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
@@ -96,13 +97,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
96 if (m_aScene == null) 97 if (m_aScene == null)
97 m_aScene = scene; 98 m_aScene = scene;
98 99
100 m_Scenes.Add(scene);
99 scene.RegisterModuleInterface<IEntityTransferModule>(this); 101 scene.RegisterModuleInterface<IEntityTransferModule>(this);
100 scene.EventManager.OnNewClient += OnNewClient; 102 scene.EventManager.OnNewClient += OnNewClient;
101 } 103 }
102 104
103 protected virtual void OnNewClient(IClientAPI client) 105 protected virtual void OnNewClient(IClientAPI client)
104 { 106 {
105 client.OnTeleportHomeRequest += TeleportHomeFired; 107 client.OnTeleportHomeRequest += TriggerTeleportHome;
108 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
106 } 109 }
107 110
108 public virtual void Close() 111 public virtual void Close()
@@ -118,6 +121,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
118 return; 121 return;
119 if (scene == m_aScene) 122 if (scene == m_aScene)
120 m_aScene = null; 123 m_aScene = null;
124
125 m_Scenes.Remove(scene);
121 } 126 }
122 127
123 public virtual void RegionLoaded(Scene scene) 128 public virtual void RegionLoaded(Scene scene)
@@ -127,7 +132,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
127 132
128 } 133 }
129 134
130
131 #endregion 135 #endregion
132 136
133 #region Agent Teleports 137 #region Agent Teleports
@@ -249,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
249 } 253 }
250 } 254 }
251 255
252 protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) 256 public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
253 { 257 {
254 if (reg == null || finalDestination == null) 258 if (reg == null || finalDestination == null)
255 { 259 {
@@ -557,9 +561,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
557 561
558 #endregion 562 #endregion
559 563
564 #region Landmark Teleport
565 /// <summary>
566 /// Tries to teleport agent to landmark.
567 /// </summary>
568 /// <param name="remoteClient"></param>
569 /// <param name="regionHandle"></param>
570 /// <param name="position"></param>
571 public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
572 {
573 GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
574
575 if (info == null)
576 {
577 // can't find the region: Tell viewer and abort
578 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
579 return;
580 }
581 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
582 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
583 }
584
585 #endregion
586
560 #region Teleport Home 587 #region Teleport Home
561 588
562 public void TeleportHomeFired(UUID id, IClientAPI client) 589 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
563 { 590 {
564 TeleportHome(id, client); 591 TeleportHome(id, client);
565 } 592 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 1ccbcfd..d6ef5df 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -86,7 +86,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
86 86
87 protected override void OnNewClient(IClientAPI client) 87 protected override void OnNewClient(IClientAPI client)
88 { 88 {
89 client.OnTeleportHomeRequest += TeleportHomeFired; 89 client.OnTeleportHomeRequest += TriggerTeleportHome;
90 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
90 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); 91 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
91 } 92 }
92 93
@@ -178,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
178 return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); 179 return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
179 } 180 }
180 181
181 public void TeleportHomeFired(UUID id, IClientAPI client) 182 public void TriggerTeleportHome(UUID id, IClientAPI client)
182 { 183 {
183 TeleportHome(id, client); 184 TeleportHome(id, client);
184 } 185 }
@@ -233,6 +234,58 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
233 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); 234 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
234 return true; 235 return true;
235 } 236 }
237
238 /// <summary>
239 /// Tries to teleport agent to landmark.
240 /// </summary>
241 /// <param name="remoteClient"></param>
242 /// <param name="regionHandle"></param>
243 /// <param name="position"></param>
244 public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
245 {
246 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
247 (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
248 if (lm.Gatekeeper == string.Empty)
249 {
250 base.RequestTeleportLandmark(remoteClient, lm);
251 return;
252 }
253
254 GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
255
256 // Local region?
257 if (info != null)
258 {
259 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
260 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
261 return;
262 }
263 else
264 {
265 // Foreign region
266 Scene scene = (Scene)(remoteClient.Scene);
267 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
268 GridRegion gatekeeper = new GridRegion();
269 gatekeeper.ServerURI = lm.Gatekeeper;
270 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID));
271 if (finalDestination != null)
272 {
273 ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
274 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
275 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
276 if (transferMod != null && sp != null && eq != null)
277 transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position,
278 Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq);
279 }
280
281 }
282
283 // can't find the region: Tell viewer and abort
284 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
285
286 }
287
288
236 #endregion 289 #endregion
237 290
238 #region IUserAgentVerificationModule 291 #region IUserAgentVerificationModule
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 52791cb..49d484b 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
56 56
57 private string m_ProfileServerURI; 57 private string m_ProfileServerURI;
58 private bool m_OutboundPermission; 58 private bool m_OutboundPermission;
59 private string m_ThisGatekeeper;
59 60
60// private bool m_Initialized = false; 61// private bool m_Initialized = false;
61 62
@@ -85,6 +86,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
85 { 86 {
86 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); 87 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
87 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); 88 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
89 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
88 } 90 }
89 else 91 else
90 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); 92 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
@@ -110,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
110 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) 112 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
111 { 113 {
112 string userAssetServer = string.Empty; 114 string userAssetServer = string.Empty;
113 if (IsForeignUser(avatarID, out userAssetServer) && m_OutboundPermission) 115 if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
114 { 116 {
115 Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); }); 117 Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
116 } 118 }
@@ -119,6 +121,24 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
119 #endregion 121 #endregion
120 122
121 #region Overrides of Basic Inventory Access methods 123 #region Overrides of Basic Inventory Access methods
124
125 protected override string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
126 {
127 UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, presence.UUID);
128 if (account == null)
129 prefix = "HG ";
130 else
131 prefix = string.Empty;
132 suffix = " @ " + m_ThisGatekeeper;
133 Vector3 pos = presence.AbsolutePosition;
134 return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}\n",
135 presence.Scene.RegionInfo.RegionID,
136 pos.X, pos.Y, pos.Z,
137 presence.RegionHandle,
138 m_ThisGatekeeper);
139 }
140
141
122 /// 142 ///
123 /// CapsUpdateInventoryItemAsset 143 /// CapsUpdateInventoryItemAsset
124 /// 144 ///
@@ -180,10 +200,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
180 public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) 200 public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
181 { 201 {
182 string userAssetServer = string.Empty; 202 string userAssetServer = string.Empty;
183 if (IsForeignUser(sender, out userAssetServer)) 203 if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty)
184 m_assMapper.Get(item.AssetID, sender, userAssetServer); 204 m_assMapper.Get(item.AssetID, sender, userAssetServer);
185 205
186 if (IsForeignUser(receiver, out userAssetServer) && m_OutboundPermission) 206 if (IsForeignUser(receiver, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
187 m_assMapper.Post(item.AssetID, receiver, userAssetServer); 207 m_assMapper.Post(item.AssetID, receiver, userAssetServer);
188 } 208 }
189 209
@@ -203,9 +223,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
203 if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) 223 if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
204 { 224 {
205 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 225 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
206 assetServerURL = assetServerURL.Trim(new char[] { '/' }); return true; 226 assetServerURL = assetServerURL.Trim(new char[] { '/' });
207 } 227 }
208 } 228 }
229 else
230 {
231 assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI");
232 assetServerURL = assetServerURL.Trim(new char[] { '/' });
233 }
234 return true;
209 } 235 }
210 236
211 return false; 237 return false;
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 184b223..7bad814 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using System.Xml; 31using System.Xml;
32using System.Reflection; 32using System.Reflection;
33using System.Text;
33using System.Threading; 34using System.Threading;
34 35
35using OpenSim.Framework; 36using OpenSim.Framework;
@@ -128,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
128 129
129 protected virtual void OnNewClient(IClientAPI client) 130 protected virtual void OnNewClient(IClientAPI client)
130 { 131 {
131 132 client.OnCreateNewInventoryItem += CreateNewInventoryItem;
132 } 133 }
133 134
134 public virtual void Close() 135 public virtual void Close()
@@ -157,6 +158,87 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
157 #region Inventory Access 158 #region Inventory Access
158 159
159 /// <summary> 160 /// <summary>
161 /// Create a new inventory item. Called when the client creates a new item directly within their
162 /// inventory (e.g. by selecting a context inventory menu option).
163 /// </summary>
164 /// <param name="remoteClient"></param>
165 /// <param name="transactionID"></param>
166 /// <param name="folderID"></param>
167 /// <param name="callbackID"></param>
168 /// <param name="description"></param>
169 /// <param name="name"></param>
170 /// <param name="invType"></param>
171 /// <param name="type"></param>
172 /// <param name="wearableType"></param>
173 /// <param name="nextOwnerMask"></param>
174 public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
175 uint callbackID, string description, string name, sbyte invType,
176 sbyte assetType,
177 byte wearableType, uint nextOwnerMask, int creationDate)
178 {
179 m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
180
181 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
182 return;
183
184 InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
185 InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f);
186
187 if (folder == null || folder.Owner != remoteClient.AgentId)
188 return;
189
190 if (transactionID == UUID.Zero)
191 {
192 ScenePresence presence;
193 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
194 {
195 byte[] data = null;
196
197 if (invType == (sbyte)InventoryType.Landmark && presence != null)
198 {
199 string suffix = string.Empty, prefix = string.Empty;
200 string strdata = GenerateLandmark(presence, out prefix, out suffix);
201 data = Encoding.ASCII.GetBytes(strdata);
202 name = prefix + name;
203 description += suffix;
204 }
205
206 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
207 m_Scene.AssetService.Store(asset);
208
209 m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
210 }
211 else
212 {
213 m_log.ErrorFormat(
214 "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
215 remoteClient.AgentId);
216 }
217 }
218 else
219 {
220 IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface<IAgentAssetTransactions>();
221 if (agentTransactions != null)
222 {
223 agentTransactions.HandleItemCreationFromTransaction(
224 remoteClient, transactionID, folderID, callbackID, description,
225 name, invType, assetType, wearableType, nextOwnerMask);
226 }
227 }
228 }
229
230 protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
231 {
232 prefix = string.Empty;
233 suffix = string.Empty;
234 Vector3 pos = presence.AbsolutePosition;
235 return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
236 presence.Scene.RegionInfo.RegionID,
237 pos.X, pos.Y, pos.Z,
238 presence.RegionHandle);
239 }
240
241 /// <summary>
160 /// Capability originating call to update the asset of an item in an agent's inventory 242 /// Capability originating call to update the asset of an item in an agent's inventory
161 /// </summary> 243 /// </summary>
162 /// <param name="remoteClient"></param> 244 /// <param name="remoteClient"></param>
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 4cc6905..ae4336c 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -30,11 +30,13 @@ using System.IO;
30using System.Reflection; 30using System.Reflection;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Console;
33 34
34using OpenSim.Region.Framework; 35using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
39using OpenSim.Services.Connectors.Hypergrid;
38 40
39using OpenMetaverse; 41using OpenMetaverse;
40using log4net; 42using log4net;
@@ -47,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
47 public UUID Id; 49 public UUID Id;
48 public string FirstName; 50 public string FirstName;
49 public string LastName; 51 public string LastName;
50 public string ProfileURL; 52 public string HomeURL;
53 public Dictionary<string, object> ServerURLs;
51 } 54 }
52 55
53 public class UserManagementModule : ISharedRegionModule, IUserManagement 56 public class UserManagementModule : ISharedRegionModule, IUserManagement
@@ -78,6 +81,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
78 // } 81 // }
79 // } 82 // }
80 //} 83 //}
84 MainConsole.Instance.Commands.AddCommand("grid", true,
85 "show user-names",
86 "show user-names",
87 "Show the bindings between user UUIDs and user names",
88 String.Empty,
89 HandleShowUsers);
90
91
81 } 92 }
82 93
83 public bool IsSharedModule 94 public bool IsSharedModule
@@ -101,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
101 112
102 scene.RegisterModuleInterface<IUserManagement>(this); 113 scene.RegisterModuleInterface<IUserManagement>(this);
103 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); 114 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
115 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
104 } 116 }
105 117
106 public void RemoveRegion(Scene scene) 118 public void RemoveRegion(Scene scene)
@@ -109,18 +121,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
109 m_Scenes.Remove(scene); 121 m_Scenes.Remove(scene);
110 } 122 }
111 123
112 public void RegionLoaded(Scene scene) 124 public void RegionLoaded(Scene s)
113 { 125 {
114 } 126 }
115 127
116 public void PostInitialise() 128 public void PostInitialise()
117 { 129 {
118 foreach (Scene s in m_Scenes)
119 {
120 // let's sniff all the user names referenced by objects in the scene
121 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
122 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
123 }
124 } 130 }
125 131
126 public void Close() 132 public void Close()
@@ -134,6 +140,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
134 140
135 #region Event Handlers 141 #region Event Handlers
136 142
143 void EventManager_OnPrimsLoaded(Scene s)
144 {
145 // let's sniff all the user names referenced by objects in the scene
146 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
147 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
148 }
149
150
137 void EventManager_OnNewClient(IClientAPI client) 151 void EventManager_OnNewClient(IClientAPI client)
138 { 152 {
139 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); 153 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
@@ -150,6 +164,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
150 string[] names = GetUserNames(uuid); 164 string[] names = GetUserNames(uuid);
151 if (names.Length == 2) 165 if (names.Length == 2)
152 { 166 {
167 //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]);
153 remote_client.SendNameReply(uuid, names[0], names[1]); 168 remote_client.SendNameReply(uuid, names[0], names[1]);
154 } 169 }
155 170
@@ -210,6 +225,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
210 225
211 public string GetUserName(UUID uuid) 226 public string GetUserName(UUID uuid)
212 { 227 {
228 //m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
213 string[] names = GetUserNames(uuid); 229 string[] names = GetUserNames(uuid);
214 if (names.Length == 2) 230 if (names.Length == 2)
215 { 231 {
@@ -222,6 +238,60 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
222 return "(hippos)"; 238 return "(hippos)";
223 } 239 }
224 240
241 public string GetUserHomeURL(UUID userID)
242 {
243 if (m_UserCache.ContainsKey(userID))
244 return m_UserCache[userID].HomeURL;
245
246 return string.Empty;
247 }
248
249 public string GetUserServerURL(UUID userID, string serverType)
250 {
251 if (m_UserCache.ContainsKey(userID))
252 {
253 UserData userdata = m_UserCache[userID];
254 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
255 return userdata.ServerURLs[serverType].ToString();
256
257 if (userdata.HomeURL != string.Empty)
258 {
259 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
260 userdata.ServerURLs = uConn.GetServerURLs(userID);
261 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
262 return userdata.ServerURLs[serverType].ToString();
263 }
264 }
265
266 return string.Empty;
267 }
268
269 public string GetUserUUI(UUID userID)
270 {
271 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
272 if (account != null)
273 return userID.ToString();
274
275 if (m_UserCache.ContainsKey(userID))
276 {
277 UserData ud = m_UserCache[userID];
278 string homeURL = ud.HomeURL;
279 string first = ud.FirstName, last = ud.LastName;
280 if (ud.LastName.StartsWith("@"))
281 {
282 string[] parts = ud.FirstName.Split('.');
283 if (parts.Length >= 2)
284 {
285 first = parts[0];
286 last = parts[1];
287 }
288 return userID + ";" + homeURL + ";" + first + " " + last;
289 }
290 }
291
292 return userID.ToString();
293 }
294
225 public void AddUser(UUID id, string creatorData) 295 public void AddUser(UUID id, string creatorData)
226 { 296 {
227 if (m_UserCache.ContainsKey(id)) 297 if (m_UserCache.ContainsKey(id))
@@ -247,13 +317,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
247 string[] parts = creatorData.Split(';'); 317 string[] parts = creatorData.Split(';');
248 if (parts.Length >= 1) 318 if (parts.Length >= 1)
249 { 319 {
250 user.ProfileURL = parts[0]; 320 user.HomeURL = parts[0];
251 try 321 try
252 { 322 {
253 Uri uri = new Uri(parts[0]); 323 Uri uri = new Uri(parts[0]);
254 user.LastName = "@" + uri.Authority; 324 user.LastName = "@" + uri.Authority;
255 } 325 }
256 catch 326 catch (UriFormatException)
257 { 327 {
258 m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]); 328 m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
259 user.LastName = "@unknown"; 329 user.LastName = "@unknown";
@@ -272,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
272 lock (m_UserCache) 342 lock (m_UserCache)
273 m_UserCache[id] = user; 343 m_UserCache[id] = user;
274 344
275 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL); 345 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL);
276 } 346 }
277 347
278 public void AddUser(UUID uuid, string first, string last, string profileURL) 348 public void AddUser(UUID uuid, string first, string last, string profileURL)
@@ -311,5 +381,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
311 //} 381 //}
312 382
313 #endregion IUserManagement 383 #endregion IUserManagement
384
385 private void HandleShowUsers(string module, string[] cmd)
386 {
387 if (m_UserCache.Count == 0)
388 {
389 MainConsole.Instance.Output("No users not found");
390 return;
391 }
392
393 MainConsole.Instance.Output("UUID User Name");
394 MainConsole.Instance.Output("-----------------------------------------------------------------------------");
395 foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
396 {
397 MainConsole.Instance.Output(String.Format("{0} {1} {2}",
398 kvp.Key, kvp.Value.FirstName, kvp.Value.LastName));
399 }
400 return;
401 }
402
403
314 } 404 }
315} 405}
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index 5ab334f..f066f83 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -25,6 +25,7 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
28using System.Collections.Generic; 29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using log4net; 31using log4net;
@@ -67,9 +68,26 @@ namespace OpenSim.Region.CoreModules.Hypergrid
67 68
68 foreach (GridRegion r in regions) 69 foreach (GridRegion r in regions)
69 { 70 {
70 MapBlockData block = new MapBlockData(); 71 uint x = 0, y = 0;
71 MapBlockFromGridRegion(block, r); 72 long handle = 0;
72 mapBlocks.Add(block); 73 if (r.RegionSecret != null && r.RegionSecret != string.Empty)
74 {
75 if (long.TryParse(r.RegionSecret, out handle))
76 {
77 Utils.LongToUInts((ulong)handle, out x, out y);
78 x = x / Constants.RegionSize;
79 y = y / Constants.RegionSize;
80 }
81 }
82
83 if (handle == 0 ||
84 // Check the distance from the current region
85 (handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096))
86 {
87 MapBlockData block = new MapBlockData();
88 MapBlockFromGridRegion(block, r);
89 mapBlocks.Add(block);
90 }
73 } 91 }
74 92
75 // Different from super 93 // Different from super
@@ -77,6 +95,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid
77 // 95 //
78 96
79 remoteClient.SendMapBlock(mapBlocks, 0); 97 remoteClient.SendMapBlock(mapBlocks, 0);
98
80 } 99 }
81 100
82 101
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index 8a6735f..e22fd38 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -24,6 +24,7 @@
24 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" /> 24 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
25 <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" /> 25 <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
26 <RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" /> 26 <RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" />
27 <RegionModule id="HGFriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.HGFriendsModule" />
27 <RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" /> 28 <RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" />
28 <RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" /> 29 <RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" />
29 <RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" /> 30 <RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" />
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
index d2343c9..a5b5637 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
@@ -113,8 +113,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
113 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); 113 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
114 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); 114 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
115 115
116 new UserAgentServerConnector(m_Config, MainServer.Instance); 116 IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
117 new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
117 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); 118 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
119 new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
118 } 120 }
119 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper); 121 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
120 } 122 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index 3f63db3..698fd56 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -58,6 +58,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
58 58
59 private List<Scene> m_Scenes = new List<Scene>(); 59 private List<Scene> m_Scenes = new List<Scene>();
60 60
61 protected IUserManagement m_UserManagement;
62 protected IUserManagement UserManagementModule
63 {
64 get
65 {
66 if (m_UserManagement == null)
67 m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>();
68 return m_UserManagement;
69 }
70 }
71
61 public Type ReplaceableInterface 72 public Type ReplaceableInterface
62 { 73 {
63 get { return null; } 74 get { return null; }
@@ -207,6 +218,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
207 } 218 }
208 } 219 }
209 } 220 }
221 if (sp == null)
222 {
223 inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI");
224 if (inventoryURL != null && inventoryURL != string.Empty)
225 {
226 inventoryURL = inventoryURL.Trim(new char[] { '/' });
227 m_InventoryURLs.Add(userID, inventoryURL);
228 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
229 }
230
231 }
232
210 } 233 }
211 } 234 }
212 235
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 5da1656..eb00de8 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -230,6 +230,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
230 /// <param name="asset"></param> 230 /// <param name="asset"></param>
231 public void AssetRequestCallback(string id, object sender, AssetBase asset) 231 public void AssetRequestCallback(string id, object sender, AssetBase asset)
232 { 232 {
233 Culture.SetCurrentCulture();
234
233 try 235 try
234 { 236 {
235 lock (this) 237 lock (this)
@@ -289,6 +291,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
289 /// </summary> 291 /// </summary>
290 protected void PerformAssetsRequestCallback(object o) 292 protected void PerformAssetsRequestCallback(object o)
291 { 293 {
294 Culture.SetCurrentCulture();
295
292 try 296 try
293 { 297 {
294 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids); 298 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index a098ff6..43b37c7 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -548,18 +548,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
548 548
549 // libomv will moan about PrimFlags.ObjectYouOfficer being 549 // libomv will moan about PrimFlags.ObjectYouOfficer being
550 // deprecated 550 // deprecated
551 #pragma warning disable 0612 551#pragma warning disable 0612
552 objflags &= (uint) 552 objflags &= (uint)
553 ~(PrimFlags.ObjectCopy | // Tells client you can copy the object 553 ~(PrimFlags.ObjectCopy | // Tells client you can copy the object
554 PrimFlags.ObjectModify | // tells client you can modify the object 554 PrimFlags.ObjectModify | // tells client you can modify the object
555 PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) 555 PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
556 PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it 556 PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
557 PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object 557 PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
558 PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object 558 PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
559 PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object 559 PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
560 PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set 560 PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
561 ); 561 );
562 #pragma warning restore 0612 562#pragma warning restore 0612
563 563
564 // Creating the three ObjectFlags options for this method to choose from. 564 // Creating the three ObjectFlags options for this method to choose from.
565 // Customize the OwnerMask 565 // Customize the OwnerMask
@@ -576,22 +576,27 @@ namespace OpenSim.Region.CoreModules.World.Permissions
576 576
577 if (m_bypassPermissions) 577 if (m_bypassPermissions)
578 return objectOwnerMask; 578 return objectOwnerMask;
579 579
580 // Object owners should be able to edit their own content 580 // Object owners should be able to edit their own content
581 if (user == objectOwner) 581 if (user == objectOwner)
582 return objectOwnerMask; 582 return objectOwnerMask;
583 583
584 if (IsFriendWithPerms(user, objectOwner)) 584 if (IsFriendWithPerms(user, objectOwner))
585 {
585 return objectOwnerMask; 586 return objectOwnerMask;
586 587 }
587 // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set 588 // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
588 if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) 589 if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
590 {
589 return objectOwnerMask; 591 return objectOwnerMask;
592 }
590 593
591 // Admin should be able to edit anything in the sim (including admin objects) 594 // Admin should be able to edit anything in the sim (including admin objects)
592 if (IsAdministrator(user)) 595 if (IsAdministrator(user))
596 {
593 return objectOwnerMask; 597 return objectOwnerMask;
594 598 }
599
595 // Users should be able to edit what is over their land. 600 // Users should be able to edit what is over their land.
596 Vector3 taskPos = task.AbsolutePosition; 601 Vector3 taskPos = task.AbsolutePosition;
597 ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); 602 ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
@@ -599,13 +604,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions
599 { 604 {
600 // Admin objects should not be editable by the above 605 // Admin objects should not be editable by the above
601 if (!IsAdministrator(objectOwner)) 606 if (!IsAdministrator(objectOwner))
607 {
602 return objectOwnerMask; 608 return objectOwnerMask;
609 }
603 } 610 }
604 611
605 // Group permissions 612 // Group permissions
606 if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) 613 if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
607 return objectGroupMask | objectEveryoneMask; 614 return objectGroupMask | objectEveryoneMask;
608 615
609 return objectEveryoneMask; 616 return objectEveryoneMask;
610 } 617 }
611 618
@@ -673,7 +680,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
673 // 680 //
674 // Nobody but the object owner can set permissions on an object 681 // Nobody but the object owner can set permissions on an object
675 // 682 //
676
677 if (locked && (!IsAdministrator(currentUser)) && denyOnLocked) 683 if (locked && (!IsAdministrator(currentUser)) && denyOnLocked)
678 { 684 {
679 return false; 685 return false;
@@ -704,6 +710,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
704 // Return immediately, so that the administrator can shares group objects 710 // Return immediately, so that the administrator can shares group objects
705 return true; 711 return true;
706 } 712 }
713
714 // Friends with benefits should be able to edit the objects too
715 if (IsFriendWithPerms(currentUser, objectOwner))
716 // Return immediately, so that the administrator can share objects with friends
717 return true;
707 718
708 // Users should be able to edit what is over their land. 719 // Users should be able to edit what is over their land.
709 ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y); 720 ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index cd40c5d..3f6f359 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -208,52 +208,65 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
208 //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", 208 //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}",
209 // path, param, agentID.ToString()); 209 // path, param, agentID.ToString());
210 210
211 // this is here because CAPS map requests work even beyond the 10,000 limit. 211 // There is a major hack going on in this method. The viewer doesn't request
212 ScenePresence avatarPresence = null; 212 // map blocks (RequestMapBlocks) above 4096. That means that if we don't hack,
213 213 // grids above that cell don't have a map at all. So, here's the hack: we wait
214 m_scene.TryGetScenePresence(agentID, out avatarPresence); 214 // for this CAP request to come, and we inject the map blocks at this point.
215 215 // In a normal scenario, this request simply sends back the MapLayer (the blue color).
216 if (avatarPresence != null) 216 // In the hacked scenario, it also sends the map blocks via UDP.
217 //
218 // 6/8/2011 -- I'm adding an explicit 4096 check, so that we never forget that there is
219 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
220
221 if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY >= 4096)
217 { 222 {
218 bool lookup = false; 223 ScenePresence avatarPresence = null;
219 224
220 lock (cachedMapBlocks) 225 m_scene.TryGetScenePresence(agentID, out avatarPresence);
221 {
222 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
223 {
224 List<MapBlockData> mapBlocks;
225 226
226 mapBlocks = cachedMapBlocks; 227 if (avatarPresence != null)
227 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
228 }
229 else
230 {
231 lookup = true;
232 }
233 }
234 if (lookup)
235 { 228 {
236 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 229 bool lookup = false;
237 230
238 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 231 lock (cachedMapBlocks)
239 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
240 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
241 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
242 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
243 foreach (GridRegion r in regions)
244 { 232 {
245 MapBlockData block = new MapBlockData(); 233 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
246 MapBlockFromGridRegion(block, r); 234 {
247 mapBlocks.Add(block); 235 List<MapBlockData> mapBlocks;
236
237 mapBlocks = cachedMapBlocks;
238 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
239 }
240 else
241 {
242 lookup = true;
243 }
248 } 244 }
249 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 245 if (lookup)
246 {
247 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
248
249 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
250 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
251 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
252 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
253 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
254 foreach (GridRegion r in regions)
255 {
256 MapBlockData block = new MapBlockData();
257 MapBlockFromGridRegion(block, r);
258 mapBlocks.Add(block);
259 }
260 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
250 261
251 lock (cachedMapBlocks) 262 lock (cachedMapBlocks)
252 cachedMapBlocks = mapBlocks; 263 cachedMapBlocks = mapBlocks;
253 264
254 cachedTime = Util.UnixTimeSinceEpoch(); 265 cachedTime = Util.UnixTimeSinceEpoch();
266 }
255 } 267 }
256 } 268 }
269
257 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 270 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
258 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 271 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
259 return mapResponse.ToString(); 272 return mapResponse.ToString();