aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs458
1 files changed, 360 insertions, 98 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
index 57025bf..d232d82 100644
--- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
@@ -57,6 +57,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserProfilesModule")] 57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserProfilesModule")]
58 public class UserProfileModule : IProfileModule, INonSharedRegionModule 58 public class UserProfileModule : IProfileModule, INonSharedRegionModule
59 { 59 {
60 const double PROFILECACHEEXPIRE = 300;
60 /// <summary> 61 /// <summary>
61 /// Logging 62 /// Logging
62 /// </summary> 63 /// </summary>
@@ -67,6 +68,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
67 // count. The entries are removed when the interest count reaches 0. 68 // count. The entries are removed when the interest count reaches 0.
68 Dictionary<UUID, UUID> m_classifiedCache = new Dictionary<UUID, UUID>(); 69 Dictionary<UUID, UUID> m_classifiedCache = new Dictionary<UUID, UUID>();
69 Dictionary<UUID, int> m_classifiedInterest = new Dictionary<UUID, int>(); 70 Dictionary<UUID, int> m_classifiedInterest = new Dictionary<UUID, int>();
71 ExpiringCache<UUID, UserProfileCacheEntry> m_profilesCache = new ExpiringCache<UUID, UserProfileCacheEntry>();
72 IImprovedAssetCache m_assetCache;
70 73
71 private JsonRpcRequestManager rpc = new JsonRpcRequestManager(); 74 private JsonRpcRequestManager rpc = new JsonRpcRequestManager();
72 private bool m_allowUserProfileWebURLs = true; 75 private bool m_allowUserProfileWebURLs = true;
@@ -128,7 +131,6 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
128 get; private set; 131 get; private set;
129 } 132 }
130 133
131
132 #region IRegionModuleBase implementation 134 #region IRegionModuleBase implementation
133 /// <summary> 135 /// <summary>
134 /// This is called to initialize the region module. For shared modules, this is called exactly once, after 136 /// This is called to initialize the region module. For shared modules, this is called exactly once, after
@@ -185,22 +187,11 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
185 Scene = scene; 187 Scene = scene;
186 Scene.RegisterModuleInterface<IProfileModule>(this); 188 Scene.RegisterModuleInterface<IProfileModule>(this);
187 Scene.EventManager.OnNewClient += OnNewClient; 189 Scene.EventManager.OnNewClient += OnNewClient;
188 Scene.EventManager.OnMakeRootAgent += HandleOnMakeRootAgent; 190 Scene.EventManager.OnClientClosed += OnClientClosed;
189 191
190 UserManagementModule = Scene.RequestModuleInterface<IUserManagement>(); 192 UserManagementModule = Scene.RequestModuleInterface<IUserManagement>();
191 } 193 }
192 194
193 void HandleOnMakeRootAgent (ScenePresence obj)
194 {
195 if(obj.PresenceType == PresenceType.Npc)
196 return;
197
198 Util.FireAndForget(delegate
199 {
200 GetImageAssets(((IScenePresence)obj).UUID);
201 }, null, "UserProfileModule.GetImageAssets");
202 }
203
204 /// <summary> 195 /// <summary>
205 /// Removes the region. 196 /// Removes the region.
206 /// </summary> 197 /// </summary>
@@ -211,6 +202,10 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
211 { 202 {
212 if(!Enabled) 203 if(!Enabled)
213 return; 204 return;
205
206 m_profilesCache.Clear();
207 m_classifiedCache.Clear();
208 m_classifiedInterest.Clear();
214 } 209 }
215 210
216 /// <summary> 211 /// <summary>
@@ -226,6 +221,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
226 { 221 {
227 if(!Enabled) 222 if(!Enabled)
228 return; 223 return;
224 m_assetCache = Scene.RequestModuleInterface<IImprovedAssetCache>();
229 } 225 }
230 226
231 /// <summary> 227 /// <summary>
@@ -297,6 +293,40 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
297 client.OnUserInfoRequest += UserPreferencesRequest; 293 client.OnUserInfoRequest += UserPreferencesRequest;
298 client.OnUpdateUserInfo += UpdateUserPreferences; 294 client.OnUpdateUserInfo += UpdateUserPreferences;
299 } 295 }
296
297 void OnClientClosed(UUID AgentId, Scene scene)
298 {
299 ScenePresence sp = scene.GetScenePresence(AgentId);
300 IClientAPI client = sp.ControllingClient;
301 if (client == null)
302 return;
303
304 //Profile
305 client.OnRequestAvatarProperties -= RequestAvatarProperties;
306 client.OnUpdateAvatarProperties -= AvatarPropertiesUpdate;
307 client.OnAvatarInterestUpdate -= AvatarInterestsUpdate;
308
309 // Classifieds
310// client.r GenericPacketHandler("avatarclassifiedsrequest", ClassifiedsRequest);
311 client.OnClassifiedInfoUpdate -= ClassifiedInfoUpdate;
312 client.OnClassifiedInfoRequest -= ClassifiedInfoRequest;
313 client.OnClassifiedDelete -= ClassifiedDelete;
314
315 // Picks
316// client.AddGenericPacketHandler("avatarpicksrequest", PicksRequest);
317// client.AddGenericPacketHandler("pickinforequest", PickInfoRequest);
318 client.OnPickInfoUpdate -= PickInfoUpdate;
319 client.OnPickDelete -= PickDelete;
320
321 // Notes
322// client.AddGenericPacketHandler("avatarnotesrequest", NotesRequest);
323 client.OnAvatarNotesUpdate -= NotesUpdate;
324
325 // Preferences
326 client.OnUserInfoRequest -= UserPreferencesRequest;
327 client.OnUpdateUserInfo -= UpdateUserPreferences;
328 }
329
300 #endregion Region Event Handlers 330 #endregion Region Event Handlers
301 331
302 #region Classified 332 #region Classified
@@ -332,6 +362,34 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
332 return; 362 return;
333 } 363 }
334 364
365 UserProfileCacheEntry uce = null;
366 lock(m_profilesCache)
367 {
368 if(m_profilesCache.TryGetValue(targetID, out uce) && uce != null)
369 {
370 if(uce.classifiedsLists != null)
371 {
372 foreach(KeyValuePair<UUID,string> kvp in uce.classifiedsLists)
373 {
374 UUID kvpkey = kvp.Key;
375 classifieds[kvpkey] = kvp.Value;
376 lock (m_classifiedCache)
377 {
378 if (!m_classifiedCache.ContainsKey(kvpkey))
379 {
380 m_classifiedCache.Add(kvpkey,targetID);
381 m_classifiedInterest.Add(kvpkey, 0);
382 }
383
384 m_classifiedInterest[kvpkey]++;
385 }
386 }
387 remoteClient.SendAvatarClassifiedReply(targetID, uce.classifiedsLists);
388 return;
389 }
390 }
391 }
392
335 string serverURI = string.Empty; 393 string serverURI = string.Empty;
336 GetUserProfileServerURI(targetID, out serverURI); 394 GetUserProfileServerURI(targetID, out serverURI);
337 if(string.IsNullOrWhiteSpace(serverURI)) 395 if(string.IsNullOrWhiteSpace(serverURI))
@@ -380,6 +438,15 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
380 } 438 }
381 } 439 }
382 440
441 lock(m_profilesCache)
442 {
443 if(!m_profilesCache.TryGetValue(targetID, out uce) || uce == null)
444 uce = new UserProfileCacheEntry();
445 uce.classifiedsLists = classifieds;
446
447 m_profilesCache.AddOrUpdate(targetID, uce, PROFILECACHEEXPIRE);
448 }
449
383 remoteClient.SendAvatarClassifiedReply(targetID, classifieds); 450 remoteClient.SendAvatarClassifiedReply(targetID, classifieds);
384 } 451 }
385 452
@@ -404,9 +471,29 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
404 } 471 }
405 } 472 }
406 } 473 }
407 474
475 UserProfileCacheEntry uce = null;
476 lock(m_profilesCache)
477 {
478 if(m_profilesCache.TryGetValue(target, out uce) && uce != null)
479 {
480 if(uce.classifieds != null && uce.classifieds.ContainsKey(queryClassifiedID))
481 {
482 ad = uce.classifieds[queryClassifiedID];
483 Vector3 gPos = new Vector3();
484 Vector3.TryParse(ad.GlobalPos, out gPos);
485
486 remoteClient.SendClassifiedInfoReply(ad.ClassifiedId, ad.CreatorId, (uint)ad.CreationDate,
487 (uint)ad.ExpirationDate, (uint)ad.Category, ad.Name, ad.Description,
488 ad.ParcelId, (uint)ad.ParentEstate, ad.SnapshotId, ad.SimName,
489 gPos, ad.ParcelName, ad.Flags, ad.Price);
490 return;
491 }
492 }
493 }
494
408 string serverURI = string.Empty; 495 string serverURI = string.Empty;
409 GetUserProfileServerURI(target, out serverURI); 496 bool foreign = GetUserProfileServerURI(target, out serverURI);
410 if(string.IsNullOrWhiteSpace(serverURI)) 497 if(string.IsNullOrWhiteSpace(serverURI))
411 { 498 {
412 return; 499 return;
@@ -424,6 +511,20 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
424 if(ad.CreatorId == UUID.Zero) 511 if(ad.CreatorId == UUID.Zero)
425 return; 512 return;
426 513
514 if(foreign)
515 cacheForeignImage(target, ad.SnapshotId);
516
517 lock(m_profilesCache)
518 {
519 if(!m_profilesCache.TryGetValue(target, out uce) || uce == null)
520 uce = new UserProfileCacheEntry();
521 if(uce.classifieds == null)
522 uce.classifieds = new Dictionary<UUID, UserClassifiedAdd>();
523 uce.classifieds[ad.ClassifiedId] = ad;
524
525 m_profilesCache.AddOrUpdate(target, uce, PROFILECACHEEXPIRE);
526 }
527
427 Vector3 globalPos = new Vector3(); 528 Vector3 globalPos = new Vector3();
428 Vector3.TryParse(ad.GlobalPos, out globalPos); 529 Vector3.TryParse(ad.GlobalPos, out globalPos);
429 530
@@ -479,13 +580,25 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
479 UUID creatorId = remoteClient.AgentId; 580 UUID creatorId = remoteClient.AgentId;
480 ScenePresence p = FindPresence(creatorId); 581 ScenePresence p = FindPresence(creatorId);
481 582
583 UserProfileCacheEntry uce = null;
584 lock(m_profilesCache)
585 m_profilesCache.TryGetValue(remoteClient.AgentId, out uce);
586
482 string serverURI = string.Empty; 587 string serverURI = string.Empty;
483 GetUserProfileServerURI(remoteClient.AgentId, out serverURI); 588 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
484 if(string.IsNullOrWhiteSpace(serverURI)) 589 if(string.IsNullOrWhiteSpace(serverURI))
485 { 590 {
486 return; 591 return;
487 } 592 }
488 593
594 if(foreign)
595 {
596 remoteClient.SendAgentAlertMessage("Please change classifieds on your home grid", true);
597 if(uce != null && uce.classifiedsLists != null)
598 remoteClient.SendAvatarClassifiedReply(remoteClient.AgentId, uce.classifiedsLists);
599 return;
600 }
601
489 OSDMap parameters = new OSDMap {{"creatorId", OSD.FromUUID(creatorId)}}; 602 OSDMap parameters = new OSDMap {{"creatorId", OSD.FromUUID(creatorId)}};
490 OSD Params = (OSD)parameters; 603 OSD Params = (OSD)parameters;
491 if (!rpc.JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString())) 604 if (!rpc.JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString()))
@@ -498,17 +611,20 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
498 bool exists = list.Cast<OSDMap>().Where(map => map.ContainsKey("classifieduuid")) 611 bool exists = list.Cast<OSDMap>().Where(map => map.ContainsKey("classifieduuid"))
499 .Any(map => map["classifieduuid"].AsUUID().Equals(queryclassifiedID)); 612 .Any(map => map["classifieduuid"].AsUUID().Equals(queryclassifiedID));
500 613
614 IMoneyModule money = null;
501 if (!exists) 615 if (!exists)
502 { 616 {
503 IMoneyModule money = s.RequestModuleInterface<IMoneyModule>(); 617 money = s.RequestModuleInterface<IMoneyModule>();
504 if (money != null) 618 if (money != null)
505 { 619 {
506 if (!money.AmountCovered(remoteClient.AgentId, queryclassifiedPrice)) 620 if (!money.AmountCovered(remoteClient.AgentId, queryclassifiedPrice))
507 { 621 {
508 remoteClient.SendAgentAlertMessage("You do not have enough money to create this classified.", false); 622 remoteClient.SendAgentAlertMessage("You do not have enough money to create this classified.", false);
623 if(uce != null && uce.classifiedsLists != null)
624 remoteClient.SendAvatarClassifiedReply(remoteClient.AgentId, uce.classifiedsLists);
509 return; 625 return;
510 } 626 }
511 money.ApplyCharge(remoteClient.AgentId, queryclassifiedPrice, MoneyTransactionType.ClassifiedCharge); 627// money.ApplyCharge(remoteClient.AgentId, queryclassifiedPrice, MoneyTransactionType.ClassifiedCharge);
512 } 628 }
513 } 629 }
514 630
@@ -535,7 +651,25 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
535 if(!rpc.JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString())) 651 if(!rpc.JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString()))
536 { 652 {
537 remoteClient.SendAgentAlertMessage("Error updating classified", false); 653 remoteClient.SendAgentAlertMessage("Error updating classified", false);
654 if(uce != null && uce.classifiedsLists != null)
655 remoteClient.SendAvatarClassifiedReply(remoteClient.AgentId, uce.classifiedsLists);
656 return;
538 } 657 }
658
659 // only charge if it worked
660 if (money != null)
661 money.ApplyCharge(remoteClient.AgentId, queryclassifiedPrice, MoneyTransactionType.ClassifiedCharge);
662
663 // just flush cache for now
664 lock(m_profilesCache)
665 {
666 if(m_profilesCache.TryGetValue(remoteClient.AgentId, out uce) && uce != null)
667 {
668 uce.classifieds = null;
669 uce.classifiedsLists = null;
670 }
671 }
672
539 } 673 }
540 674
541 /// <summary> 675 /// <summary>
@@ -549,11 +683,18 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
549 /// </param> 683 /// </param>
550 public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient) 684 public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient)
551 { 685 {
686
552 string serverURI = string.Empty; 687 string serverURI = string.Empty;
553 GetUserProfileServerURI(remoteClient.AgentId, out serverURI); 688 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
554 if(string.IsNullOrWhiteSpace(serverURI)) 689 if(string.IsNullOrWhiteSpace(serverURI))
555 return; 690 return;
556 691
692 if(foreign)
693 {
694 remoteClient.SendAgentAlertMessage("Please change classifieds on your home grid", true);
695 return;
696 }
697
557 UUID classifiedId; 698 UUID classifiedId;
558 if(!UUID.TryParse(queryClassifiedID.ToString(), out classifiedId)) 699 if(!UUID.TryParse(queryClassifiedID.ToString(), out classifiedId))
559 return; 700 return;
@@ -568,6 +709,17 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
568 return; 709 return;
569 } 710 }
570 711
712 // flush cache
713 UserProfileCacheEntry uce = null;
714 lock(m_profilesCache)
715 {
716 if(m_profilesCache.TryGetValue(remoteClient.AgentId, out uce) && uce != null)
717 {
718 uce.classifieds = null;
719 uce.classifiedsLists = null;
720 }
721 }
722
571 parameters = (OSDMap)Params; 723 parameters = (OSDMap)Params;
572 } 724 }
573 #endregion Classified 725 #endregion Classified
@@ -605,6 +757,19 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
605 return; 757 return;
606 } 758 }
607 759
760 UserProfileCacheEntry uce = null;
761 lock(m_profilesCache)
762 {
763 if(m_profilesCache.TryGetValue(targetId, out uce) && uce != null)
764 {
765 if(uce != null && uce.picksList != null)
766 {
767 remoteClient.SendAvatarPicksReply(targetId, uce.picksList);
768 return;
769 }
770 }
771 }
772
608 string serverURI = string.Empty; 773 string serverURI = string.Empty;
609 GetUserProfileServerURI(targetId, out serverURI); 774 GetUserProfileServerURI(targetId, out serverURI);
610 if(string.IsNullOrWhiteSpace(serverURI)) 775 if(string.IsNullOrWhiteSpace(serverURI))
@@ -637,6 +802,16 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
637 string name = m["name"].AsString(); 802 string name = m["name"].AsString();
638 picks[cid] = name; 803 picks[cid] = name;
639 } 804 }
805
806 lock(m_profilesCache)
807 {
808 if(!m_profilesCache.TryGetValue(targetId, out uce) || uce == null)
809 uce = new UserProfileCacheEntry();
810 uce.picksList = picks;
811
812 m_profilesCache.AddOrUpdate(targetId, uce, PROFILECACHEEXPIRE);
813 }
814
640 remoteClient.SendAvatarPicksReply(targetId, picks); 815 remoteClient.SendAvatarPicksReply(targetId, picks);
641 } 816 }
642 817
@@ -667,8 +842,27 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
667 if(!UUID.TryParse (args [1], out pick.PickId)) 842 if(!UUID.TryParse (args [1], out pick.PickId))
668 return; 843 return;
669 844
845 IClientAPI remoteClient = (IClientAPI)sender;
846 UserProfileCacheEntry uce = null;
847 lock(m_profilesCache)
848 {
849 if(m_profilesCache.TryGetValue(targetID, out uce) && uce != null)
850 {
851 if(uce != null && uce.picks != null && uce.picks.ContainsKey(pick.PickId))
852 {
853 pick = uce.picks[pick.PickId];
854 Vector3 gPos = new Vector3(Vector3.Zero);
855 Vector3.TryParse(pick.GlobalPos, out gPos);
856 remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name,
857 pick.Desc,pick.SnapshotId,pick.ParcelName,pick.OriginalName,pick.SimName,
858 gPos,pick.SortOrder,pick.Enabled);
859 return;
860 }
861 }
862 }
863
670 string serverURI = string.Empty; 864 string serverURI = string.Empty;
671 GetUserProfileServerURI (targetID, out serverURI); 865 bool foreign = GetUserProfileServerURI (targetID, out serverURI);
672 if(string.IsNullOrWhiteSpace(serverURI)) 866 if(string.IsNullOrWhiteSpace(serverURI))
673 { 867 {
674 return; 868 return;
@@ -676,8 +870,6 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
676 870
677 string theirGatekeeperURI; 871 string theirGatekeeperURI;
678 GetUserGatekeeperURI(targetID, out theirGatekeeperURI); 872 GetUserGatekeeperURI(targetID, out theirGatekeeperURI);
679
680 IClientAPI remoteClient = (IClientAPI)sender;
681 873
682 object Pick = (object)pick; 874 object Pick = (object)pick;
683 if (!rpc.JsonRpcRequest (ref Pick, "pickinforequest", serverURI, UUID.Random ().ToString ())) { 875 if (!rpc.JsonRpcRequest (ref Pick, "pickinforequest", serverURI, UUID.Random ().ToString ())) {
@@ -686,6 +878,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
686 return; 878 return;
687 } 879 }
688 pick = (UserProfilePick)Pick; 880 pick = (UserProfilePick)Pick;
881 if(foreign)
882 cacheForeignImage(targetID, pick.SnapshotId);
689 883
690 Vector3 globalPos = new Vector3(Vector3.Zero); 884 Vector3 globalPos = new Vector3(Vector3.Zero);
691 Vector3.TryParse(pick.GlobalPos, out globalPos); 885 Vector3.TryParse(pick.GlobalPos, out globalPos);
@@ -716,6 +910,18 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
716 910
717 m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString()); 911 m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString());
718 912
913 pick.GlobalPos = globalPos.ToString();
914 lock(m_profilesCache)
915 {
916 if(!m_profilesCache.TryGetValue(targetID, out uce) || uce == null)
917 uce = new UserProfileCacheEntry();
918 if(uce.picks == null)
919 uce.picks = new Dictionary<UUID, UserProfilePick>();
920 uce.picks[pick.PickId] = pick;
921
922 m_profilesCache.AddOrUpdate(targetID, uce, PROFILECACHEEXPIRE);
923 }
924
719 // Pull the rabbit out of the hat 925 // Pull the rabbit out of the hat
720 remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name, 926 remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name,
721 pick.Desc,pick.SnapshotId,pick.ParcelName,pick.OriginalName,pick.SimName, 927 pick.Desc,pick.SnapshotId,pick.ParcelName,pick.OriginalName,pick.SimName,
@@ -754,7 +960,6 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
754 /// </param> 960 /// </param>
755 public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled) 961 public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled)
756 { 962 {
757 //TODO: See how this works with NPC, May need to test
758 m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString()); 963 m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString());
759 964
760 UserProfilePick pick = new UserProfilePick(); 965 UserProfilePick pick = new UserProfilePick();
@@ -774,15 +979,19 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
774 avaPos.Z); 979 avaPos.Z);
775 980
776 string landParcelName = "My Parcel"; 981 string landParcelName = "My Parcel";
777 UUID landParcelID = p.currentParcelUUID; 982// UUID landParcelID = p.currentParcelUUID;
778 983
984 // to locate parcels we use a fake id that encodes the region handle
985 // since we do not have a global locator
986 // this fails on HG
987 UUID landParcelID = Util.BuildFakeParcelID(remoteClient.Scene.RegionInfo.RegionHandle, (uint)avaPos.X, (uint)avaPos.Y);
779 ILandObject land = p.Scene.LandChannel.GetLandObject(avaPos.X, avaPos.Y); 988 ILandObject land = p.Scene.LandChannel.GetLandObject(avaPos.X, avaPos.Y);
780 989
781 if (land != null) 990 if (land != null)
782 { 991 {
783 // If land found, use parcel uuid from here because the value from SP will be blank if the avatar hasnt moved 992 // If land found, use parcel uuid from here because the value from SP will be blank if the avatar hasnt moved
784 landParcelName = land.LandData.Name; 993 landParcelName = land.LandData.Name;
785 landParcelID = land.LandData.GlobalID; 994// landParcelID = land.LandData.GlobalID;
786 } 995 }
787 else 996 else
788 { 997 {
@@ -791,7 +1000,6 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
791 avaPos.X, avaPos.Y, p.Scene.Name); 1000 avaPos.X, avaPos.Y, p.Scene.Name);
792 } 1001 }
793 1002
794
795 pick.PickId = pickID; 1003 pick.PickId = pickID;
796 pick.CreatorId = creatorID; 1004 pick.CreatorId = creatorID;
797 pick.TopPick = topPick; 1005 pick.TopPick = topPick;
@@ -814,6 +1022,24 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
814 return; 1022 return;
815 } 1023 }
816 1024
1025 UserProfileCacheEntry uce = null;
1026 lock(m_profilesCache)
1027 {
1028 if(!m_profilesCache.TryGetValue(remoteClient.AgentId, out uce) || uce == null)
1029 uce = new UserProfileCacheEntry();
1030 if(uce.picks == null)
1031 uce.picks = new Dictionary<UUID, UserProfilePick>();
1032 if(uce.picksList == null)
1033 uce.picksList = new Dictionary<UUID, string>();
1034 uce.picks[pick.PickId] = pick;
1035 uce.picksList[pick.PickId] = pick.Name;
1036 m_profilesCache.AddOrUpdate(remoteClient.AgentId, uce, PROFILECACHEEXPIRE);
1037 }
1038 remoteClient.SendAvatarPicksReply(remoteClient.AgentId, uce.picksList);
1039 remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name,
1040 pick.Desc,pick.SnapshotId,pick.ParcelName,pick.OriginalName,pick.SimName,
1041 posGlobal,pick.SortOrder,pick.Enabled);
1042
817 m_log.DebugFormat("[PROFILES]: Finish PickInfoUpdate {0} {1}", pick.Name, pick.PickId.ToString()); 1043 m_log.DebugFormat("[PROFILES]: Finish PickInfoUpdate {0} {1}", pick.Name, pick.PickId.ToString());
818 } 1044 }
819 1045
@@ -844,6 +1070,23 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
844 "Error picks delete", false); 1070 "Error picks delete", false);
845 return; 1071 return;
846 } 1072 }
1073
1074 UserProfileCacheEntry uce = null;
1075 lock(m_profilesCache)
1076 {
1077 if(m_profilesCache.TryGetValue(remoteClient.AgentId, out uce) && uce != null)
1078 {
1079 if(uce.picks != null && uce.picks.ContainsKey(queryPickID))
1080 uce.picks.Remove(queryPickID);
1081 if(uce.picksList != null && uce.picksList.ContainsKey(queryPickID))
1082 uce.picksList.Remove(queryPickID);
1083 m_profilesCache.AddOrUpdate(remoteClient.AgentId, uce, PROFILECACHEEXPIRE);
1084 }
1085 }
1086 if(uce != null && uce.picksList != null)
1087 remoteClient.SendAvatarPicksReply(remoteClient.AgentId, uce.picksList);
1088 else
1089 remoteClient.SendAvatarPicksReply(remoteClient.AgentId, new Dictionary<UUID, string>());
847 } 1090 }
848 #endregion Picks 1091 #endregion Picks
849 1092
@@ -1025,6 +1268,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1025 /// </param> 1268 /// </param>
1026 public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages) 1269 public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages)
1027 { 1270 {
1271
1028 UserProfileProperties prop = new UserProfileProperties(); 1272 UserProfileProperties prop = new UserProfileProperties();
1029 1273
1030 prop.UserId = remoteClient.AgentId; 1274 prop.UserId = remoteClient.AgentId;
@@ -1046,6 +1290,17 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1046 "Error updating interests", false); 1290 "Error updating interests", false);
1047 return; 1291 return;
1048 } 1292 }
1293
1294 // flush cache
1295 UserProfileCacheEntry uce = null;
1296 lock(m_profilesCache)
1297 {
1298 if(m_profilesCache.TryGetValue(remoteClient.AgentId, out uce) && uce != null)
1299 {
1300 uce.props = null;
1301 }
1302 }
1303
1049 } 1304 }
1050 1305
1051 public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 1306 public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
@@ -1067,6 +1322,27 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1067 0, "Getting into trouble", "Droidspeak"); 1322 0, "Getting into trouble", "Droidspeak");
1068 return; 1323 return;
1069 } 1324 }
1325 UserProfileProperties props;
1326 UserProfileCacheEntry uce = null;
1327 lock(m_profilesCache)
1328 {
1329 if(m_profilesCache.TryGetValue(avatarID, out uce) && uce != null)
1330 {
1331 if(uce.props != null)
1332 {
1333 props = uce.props;
1334 remoteClient.SendAvatarProperties(props.UserId, props.AboutText,
1335 uce.born, uce.membershipType , props.FirstLifeText, uce.flags,
1336 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId);
1337
1338
1339 remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask,
1340 props.WantToText, (uint)props.SkillsMask,
1341 props.SkillsText, props.Language);
1342 return;
1343 }
1344 }
1345 }
1070 1346
1071 string serverURI = string.Empty; 1347 string serverURI = string.Empty;
1072 bool foreign = GetUserProfileServerURI(avatarID, out serverURI); 1348 bool foreign = GetUserProfileServerURI(avatarID, out serverURI);
@@ -1118,13 +1394,13 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1118 } 1394 }
1119 } 1395 }
1120 1396
1121 UserProfileProperties props = new UserProfileProperties(); 1397 props = new UserProfileProperties();
1122 props.UserId = avatarID; 1398 props.UserId = avatarID;
1123 1399
1124 string result = string.Empty; 1400 string result = string.Empty;
1125 if(!GetProfileData(ref props, foreign, out result)) 1401 if(!GetProfileData(ref props, foreign, serverURI, out result))
1126 { 1402 {
1127 props.AboutText ="Profile not avaible at this time. User may still be unknown to this grid"; 1403 props.AboutText ="Profile not available at this time. User may still be unknown to this grid";
1128 } 1404 }
1129 1405
1130 // if on same region force online 1406 // if on same region force online
@@ -1134,10 +1410,21 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1134 if(!m_allowUserProfileWebURLs) 1410 if(!m_allowUserProfileWebURLs)
1135 props.WebUrl =""; 1411 props.WebUrl ="";
1136 1412
1413 lock(m_profilesCache)
1414 {
1415 if(!m_profilesCache.TryGetValue(props.UserId, out uce) || uce == null)
1416 uce = new UserProfileCacheEntry();
1417 uce.props = props;
1418 uce.born = born;
1419 uce.membershipType = membershipType;
1420 uce.flags = flags;
1421
1422 m_profilesCache.AddOrUpdate(props.UserId, uce, PROFILECACHEEXPIRE);
1423 }
1424
1137 remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, membershipType , props.FirstLifeText, flags, 1425 remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, membershipType , props.FirstLifeText, flags,
1138 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); 1426 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId);
1139 1427
1140
1141 remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask, 1428 remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask,
1142 props.SkillsText, props.Language); 1429 props.SkillsText, props.Language);
1143 } 1430 }
@@ -1155,6 +1442,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1155 { 1442 {
1156 if (remoteClient.AgentId == newProfile.ID) 1443 if (remoteClient.AgentId == newProfile.ID)
1157 { 1444 {
1445
1158 UserProfileProperties prop = new UserProfileProperties(); 1446 UserProfileProperties prop = new UserProfileProperties();
1159 1447
1160 prop.UserId = remoteClient.AgentId; 1448 prop.UserId = remoteClient.AgentId;
@@ -1179,6 +1467,16 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1179 return; 1467 return;
1180 } 1468 }
1181 1469
1470 // flush cache
1471 UserProfileCacheEntry uce = null;
1472 lock(m_profilesCache)
1473 {
1474 if(m_profilesCache.TryGetValue(remoteClient.AgentId, out uce) && uce != null)
1475 {
1476 uce.props = null;
1477 }
1478 }
1479
1182 RequestAvatarProperties(remoteClient, newProfile.ID); 1480 RequestAvatarProperties(remoteClient, newProfile.ID);
1183 } 1481 }
1184 } 1482 }
@@ -1189,24 +1487,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1189 /// <returns> 1487 /// <returns>
1190 /// The profile data. 1488 /// The profile data.
1191 /// </returns> 1489 /// </returns>
1192 bool GetProfileData(ref UserProfileProperties properties, bool foreign, out string message) 1490 bool GetProfileData(ref UserProfileProperties properties, bool foreign, string serverURI, out string message)
1193 { 1491 {
1194 // Can't handle NPC yet...
1195 ScenePresence p = FindPresence(properties.UserId);
1196
1197 if (null != p)
1198 {
1199 if (p.PresenceType == PresenceType.Npc)
1200 {
1201 message = "Id points to NPC";
1202 return false;
1203 }
1204 }
1205
1206 string serverURI = string.Empty;
1207 GetUserProfileServerURI(properties.UserId, out serverURI);
1208 // This is checking a friend on the home grid
1209 // Not HG friend
1210 if (String.IsNullOrEmpty(serverURI)) 1492 if (String.IsNullOrEmpty(serverURI))
1211 { 1493 {
1212 message = "User profile service unknown at this time"; 1494 message = "User profile service unknown at this time";
@@ -1247,10 +1529,14 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1247 1529
1248 return false; 1530 return false;
1249 } 1531 }
1250 // else, continue below
1251 } 1532 }
1252 1533
1253 properties = (UserProfileProperties)Prop; 1534 properties = (UserProfileProperties)Prop;
1535 if(foreign)
1536 {
1537 cacheForeignImage(properties.UserId, properties.ImageId);
1538 cacheForeignImage(properties.UserId, properties.FirstLifeImageId);
1539 }
1254 1540
1255 message = "Success"; 1541 message = "Success";
1256 return true; 1542 return true;
@@ -1258,49 +1544,6 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1258 #endregion Avatar Properties 1544 #endregion Avatar Properties
1259 1545
1260 #region Utils 1546 #region Utils
1261 bool GetImageAssets(UUID avatarId)
1262 {
1263 string profileServerURI = string.Empty;
1264 string assetServerURI = string.Empty;
1265
1266 bool foreign = GetUserProfileServerURI(avatarId, out profileServerURI);
1267
1268 if(!foreign)
1269 return true;
1270
1271 assetServerURI = UserManagementModule.GetUserServerURL(avatarId, "AssetServerURI");
1272
1273 if(string.IsNullOrEmpty(profileServerURI) || string.IsNullOrEmpty(assetServerURI))
1274 return false;
1275
1276 OSDMap parameters= new OSDMap();
1277 parameters.Add("avatarId", OSD.FromUUID(avatarId));
1278 OSD Params = (OSD)parameters;
1279 if(!rpc.JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString()))
1280 {
1281 return false;
1282 }
1283
1284 parameters = (OSDMap)Params;
1285
1286 if (parameters.ContainsKey("result"))
1287 {
1288 OSDArray list = (OSDArray)parameters["result"];
1289
1290 foreach (OSD asset in list)
1291 {
1292 OSDString assetId = (OSDString)asset;
1293
1294 Scene.AssetService.Get(string.Format("{0}/{1}", assetServerURI, assetId.AsString()));
1295 }
1296 return true;
1297 }
1298 else
1299 {
1300 m_log.ErrorFormat("[PROFILES]: Problematic response for image_assets_request from {0}", profileServerURI);
1301 return false;
1302 }
1303 }
1304 1547
1305 /// <summary> 1548 /// <summary>
1306 /// Gets the user account data. 1549 /// Gets the user account data.
@@ -1451,6 +1694,27 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1451 } 1694 }
1452 } 1695 }
1453 1696
1697 void cacheForeignImage(UUID agent, UUID imageID)
1698 {
1699 if(imageID == null || imageID == UUID.Zero)
1700 return;
1701
1702 string assetServerURI = UserManagementModule.GetUserServerURL(agent, "AssetServerURI");
1703 if(string.IsNullOrWhiteSpace(assetServerURI))
1704 return;
1705
1706 string imageIDstr = imageID.ToString();
1707
1708
1709 if(m_assetCache != null && m_assetCache.Check(imageIDstr))
1710 return;
1711
1712 if(Scene.AssetService.Get(imageIDstr) != null)
1713 return;
1714
1715 Scene.AssetService.Get(string.Format("{0}/{1}", assetServerURI, imageIDstr));
1716 }
1717
1454 /// <summary> 1718 /// <summary>
1455 /// Finds the presence. 1719 /// Finds the presence.
1456 /// </summary> 1720 /// </summary>
@@ -1519,9 +1783,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1519 webRequest.ContentType = "application/json-rpc"; 1783 webRequest.ContentType = "application/json-rpc";
1520 webRequest.Method = "POST"; 1784 webRequest.Method = "POST";
1521 1785
1522 Stream dataStream = webRequest.GetRequestStream(); 1786 using(Stream dataStream = webRequest.GetRequestStream())
1523 dataStream.Write(content, 0, content.Length); 1787 dataStream.Write(content,0,content.Length);
1524 dataStream.Close();
1525 1788
1526 WebResponse webResponse = null; 1789 WebResponse webResponse = null;
1527 try 1790 try
@@ -1601,9 +1864,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1601 webRequest.ContentType = "application/json-rpc"; 1864 webRequest.ContentType = "application/json-rpc";
1602 webRequest.Method = "POST"; 1865 webRequest.Method = "POST";
1603 1866
1604 Stream dataStream = webRequest.GetRequestStream(); 1867 using(Stream dataStream = webRequest.GetRequestStream())
1605 dataStream.Write(content, 0, content.Length); 1868 dataStream.Write(content,0,content.Length);
1606 dataStream.Close();
1607 1869
1608 WebResponse webResponse = null; 1870 WebResponse webResponse = null;
1609 try 1871 try