/// <summary> /// Updates the userpicks /// </summary> /// <param name='remoteClient'> /// Remote client. /// </param> /// <param name='pickID'> /// Pick I. /// </param> /// <param name='creatorID'> /// the creator of the pick /// </param> /// <param name='topPick'> /// Top pick. /// </param> /// <param name='name'> /// Name. /// </param> /// <param name='desc'> /// Desc. /// </param> /// <param name='snapshotID'> /// Snapshot I. /// </param> /// <param name='sortOrder'> /// Sort order. /// </param> /// <param name='enabled'> /// Enabled. /// </param> public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled) { m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString()); UserProfilePick pick = new UserProfilePick(); string serverURI = string.Empty; GetUserProfileServerURI(remoteClient.AgentId, out serverURI); if(string.IsNullOrWhiteSpace(serverURI)) { return; } ScenePresence p = FindPresence(remoteClient.AgentId); Vector3 avaPos = p.AbsolutePosition; // Getting the global position for the Avatar Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.WorldLocX + avaPos.X, remoteClient.Scene.RegionInfo.WorldLocY + avaPos.Y, avaPos.Z); string landParcelName = "My Parcel"; // UUID landParcelID = p.currentParcelUUID; // to locate parcels we use a fake id that encodes the region handle // since we do not have a global locator // this fails on HG UUID landParcelID = Util.BuildFakeParcelID(remoteClient.Scene.RegionInfo.RegionHandle, (uint)avaPos.X, (uint)avaPos.Y); ILandObject land = p.Scene.LandChannel.GetLandObject(avaPos.X, avaPos.Y); if (land != null) { // If land found, use parcel uuid from here because the value from SP will be blank if the avatar hasnt moved landParcelName = land.LandData.Name; // landParcelID = land.LandData.GlobalID; } else { m_log.WarnFormat( "[PROFILES]: PickInfoUpdate found no parcel info at {0},{1} in {2}", avaPos.X, avaPos.Y, p.Scene.Name); } pick.PickId = pickID; pick.CreatorId = creatorID; pick.TopPick = topPick; pick.Name = name; pick.Desc = desc; pick.ParcelId = landParcelID; pick.SnapshotId = snapshotID; pick.ParcelName = landParcelName; pick.SimName = remoteClient.Scene.RegionInfo.RegionName; pick.Gatekeeper = MyGatekeeper; pick.GlobalPos = posGlobal.ToString(); pick.SortOrder = sortOrder; pick.Enabled = enabled; object Pick = (object)pick; if(!rpc.JsonRpcRequest(ref Pick, "picks_update", serverURI, UUID.Random().ToString())) { remoteClient.SendAgentAlertMessage( "Error updating pick", false); return; } UserProfileCacheEntry uce = null; lock(m_profilesCache) { if(!m_profilesCache.TryGetValue(remoteClient.AgentId, out uce) || uce == null) uce = new UserProfileCacheEntry(); if(uce.picks == null) uce.picks = new Dictionary<UUID, UserProfilePick>(); if(uce.picksList == null) uce.picksList = new Dictionary<UUID, string>(); uce.picks[pick.PickId] = pick; uce.picksList[pick.PickId] = pick.Name; m_profilesCache.AddOrUpdate(remoteClient.AgentId, uce, PROFILECACHEEXPIRE); } remoteClient.SendAvatarPicksReply(remoteClient.AgentId, uce.picksList); remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name, pick.Desc,pick.SnapshotId,pick.ParcelName,pick.OriginalName,pick.SimName, posGlobal,pick.SortOrder,pick.Enabled); m_log.DebugFormat("[PROFILES]: Finish PickInfoUpdate {0} {1}", pick.Name, pick.PickId.ToString()); }
/// <summary> /// Handles the pick info request. /// </summary> /// <param name='sender'> /// Sender. /// </param> /// <param name='method'> /// Method. /// </param> /// <param name='args'> /// Arguments. /// </param> public void PickInfoRequest(Object sender, string method, List<String> args) { if (!(sender is IClientAPI)) return; UserProfilePick pick = new UserProfilePick (); UUID targetID; if(!UUID.TryParse(args [0], out targetID)) return; pick.CreatorId = targetID; if(!UUID.TryParse (args [1], out pick.PickId)) return; IClientAPI remoteClient = (IClientAPI)sender; UserProfileCacheEntry uce = null; lock(m_profilesCache) { if(m_profilesCache.TryGetValue(targetID, out uce) && uce != null) { if(uce != null && uce.picks != null && uce.picks.ContainsKey(pick.PickId)) { pick = uce.picks[pick.PickId]; Vector3 gPos = new Vector3(Vector3.Zero); Vector3.TryParse(pick.GlobalPos, out gPos); remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name, pick.Desc,pick.SnapshotId,pick.ParcelName,pick.OriginalName,pick.SimName, gPos,pick.SortOrder,pick.Enabled); return; } } } string serverURI = string.Empty; bool foreign = GetUserProfileServerURI (targetID, out serverURI); if(string.IsNullOrWhiteSpace(serverURI)) { return; } string theirGatekeeperURI; GetUserGatekeeperURI(targetID, out theirGatekeeperURI); object Pick = (object)pick; if (!rpc.JsonRpcRequest (ref Pick, "pickinforequest", serverURI, UUID.Random ().ToString ())) { remoteClient.SendAgentAlertMessage ( "Error selecting pick", false); return; } pick = (UserProfilePick)Pick; if(foreign) cacheForeignImage(targetID, pick.SnapshotId); Vector3 globalPos = new Vector3(Vector3.Zero); Vector3.TryParse(pick.GlobalPos, out globalPos); if (!string.IsNullOrWhiteSpace(MyGatekeeper) && pick.Gatekeeper != MyGatekeeper) { // Setup the illusion string region = string.Format("{0} {1}",pick.Gatekeeper,pick.SimName); GridRegion target = Scene.GridService.GetRegionByName(Scene.RegionInfo.ScopeID, region); if(target == null) { // This is a unreachable region } else { // we have a proxy on map ulong oriHandle; uint oriX; uint oriY; if(Util.ParseFakeParcelID(pick.ParcelId, out oriHandle, out oriX, out oriY)) { pick.ParcelId = Util.BuildFakeParcelID(target.RegionHandle, oriX, oriY); globalPos.X = target.RegionLocX + oriX; globalPos.Y = target.RegionLocY + oriY; pick.GlobalPos = globalPos.ToString(); } else { // this is a fail on large regions uint gtmp = (uint)globalPos.X >> 8; globalPos.X -= (gtmp << 8); gtmp = (uint)globalPos.Y >> 8; globalPos.Y -= (gtmp << 8); pick.ParcelId = Util.BuildFakeParcelID(target.RegionHandle, (uint)globalPos.X, (uint)globalPos.Y); globalPos.X += target.RegionLocX; globalPos.Y += target.RegionLocY; pick.GlobalPos = globalPos.ToString(); } } } m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString()); lock(m_profilesCache) { if(!m_profilesCache.TryGetValue(targetID, out uce) || uce == null) uce = new UserProfileCacheEntry(); if(uce.picks == null) uce.picks = new Dictionary<UUID, UserProfilePick>(); uce.picks[pick.PickId] = pick; m_profilesCache.AddOrUpdate(targetID, uce, PROFILECACHEEXPIRE); } // Pull the rabbit out of the hat remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name, pick.Desc,pick.SnapshotId,pick.ParcelName,pick.OriginalName,pick.SimName, globalPos,pick.SortOrder,pick.Enabled); }
/// <summary> /// Handles the avatar picks request. /// </summary> /// <param name='sender'> /// Sender. /// </param> /// <param name='method'> /// Method. /// </param> /// <param name='args'> /// Arguments. /// </param> public void PicksRequest(Object sender, string method, List<String> args) { if (!(sender is IClientAPI)) return; IClientAPI remoteClient = (IClientAPI)sender; UUID targetId; if(!UUID.TryParse(args[0], out targetId)) return; Dictionary<UUID, string> picks = new Dictionary<UUID, string>(); ScenePresence p = FindPresence(targetId); if (p != null && p.isNPC) { remoteClient.SendAvatarPicksReply(targetId, picks); return; } UserProfileCacheEntry uce = null; lock(m_profilesCache) { if(m_profilesCache.TryGetValue(targetId, out uce) && uce != null) { if(uce != null && uce.picksList != null) { remoteClient.SendAvatarPicksReply(targetId, uce.picksList); return; } } } string serverURI = string.Empty; GetUserProfileServerURI(targetId, out serverURI); if(string.IsNullOrWhiteSpace(serverURI)) { remoteClient.SendAvatarPicksReply(targetId, picks); return; } OSDMap parameters= new OSDMap(); parameters.Add("creatorId", OSD.FromUUID(targetId)); OSD Params = (OSD)parameters; if(!rpc.JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString())) { remoteClient.SendAvatarPicksReply(targetId, picks); return; } parameters = (OSDMap)Params; if(!parameters.ContainsKey("result") || parameters["result"] == null) { remoteClient.SendAvatarPicksReply(targetId, picks); return; } OSDArray list = (OSDArray)parameters["result"]; foreach(OSD map in list) { OSDMap m = (OSDMap)map; UUID cid = m["pickuuid"].AsUUID(); string name = m["name"].AsString(); picks[cid] = name; } lock(m_profilesCache) { if(!m_profilesCache.TryGetValue(targetId, out uce) || uce == null) uce = new UserProfileCacheEntry(); uce.picksList = picks; m_profilesCache.AddOrUpdate(targetId, uce, PROFILECACHEEXPIRE); } remoteClient.SendAvatarPicksReply(targetId, picks); }
public void ClassifiedInfoRequest(UUID queryClassifiedID, IClientAPI remoteClient) { UUID target = remoteClient.AgentId; UserClassifiedAdd ad = new UserClassifiedAdd(); ad.ClassifiedId = queryClassifiedID; lock (m_classifiedCache) { if (m_classifiedCache.ContainsKey(queryClassifiedID)) { target = m_classifiedCache[queryClassifiedID]; m_classifiedInterest[queryClassifiedID] --; if (m_classifiedInterest[queryClassifiedID] == 0) { m_classifiedInterest.Remove(queryClassifiedID); m_classifiedCache.Remove(queryClassifiedID); } } } UserProfileCacheEntry uce = null; lock(m_profilesCache) { if(m_profilesCache.TryGetValue(target, out uce) && uce != null) { if(uce.classifieds != null && uce.classifieds.ContainsKey(queryClassifiedID)) { ad = uce.classifieds[queryClassifiedID]; Vector3 gPos = new Vector3(); Vector3.TryParse(ad.GlobalPos, out gPos); remoteClient.SendClassifiedInfoReply(ad.ClassifiedId, ad.CreatorId, (uint)ad.CreationDate, (uint)ad.ExpirationDate, (uint)ad.Category, ad.Name, ad.Description, ad.ParcelId, (uint)ad.ParentEstate, ad.SnapshotId, ad.SimName, gPos, ad.ParcelName, ad.Flags, ad.Price); return; } } } string serverURI = string.Empty; bool foreign = GetUserProfileServerURI(target, out serverURI); if(string.IsNullOrWhiteSpace(serverURI)) { return; } object Ad = (object)ad; if(!rpc.JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString())) { remoteClient.SendAgentAlertMessage( "Error getting classified info", false); return; } ad = (UserClassifiedAdd) Ad; if(ad.CreatorId == UUID.Zero) return; if(foreign) cacheForeignImage(target, ad.SnapshotId); lock(m_profilesCache) { if(!m_profilesCache.TryGetValue(target, out uce) || uce == null) uce = new UserProfileCacheEntry(); if(uce.classifieds == null) uce.classifieds = new Dictionary<UUID, UserClassifiedAdd>(); uce.classifieds[ad.ClassifiedId] = ad; m_profilesCache.AddOrUpdate(target, uce, PROFILECACHEEXPIRE); } Vector3 globalPos = new Vector3(); Vector3.TryParse(ad.GlobalPos, out globalPos); remoteClient.SendClassifiedInfoReply(ad.ClassifiedId, ad.CreatorId, (uint)ad.CreationDate, (uint)ad.ExpirationDate, (uint)ad.Category, ad.Name, ad.Description, ad.ParcelId, (uint)ad.ParentEstate, ad.SnapshotId, ad.SimName, globalPos, ad.ParcelName, ad.Flags, ad.Price); }
/// /// <summary> /// Handles the avatar classifieds request. /// </summary> /// <param name='sender'> /// Sender. /// </param> /// <param name='method'> /// Method. /// </param> /// <param name='args'> /// Arguments. /// </param> public void ClassifiedsRequest(Object sender, string method, List<String> args) { if (!(sender is IClientAPI)) return; IClientAPI remoteClient = (IClientAPI)sender; Dictionary<UUID, string> classifieds = new Dictionary<UUID, string>(); UUID targetID; if(!UUID.TryParse(args[0], out targetID) || targetID == UUID.Zero) return; ScenePresence p = FindPresence(targetID); if (p != null && p.isNPC) { remoteClient.SendAvatarClassifiedReply(targetID, classifieds); return; } UserProfileCacheEntry uce = null; lock(m_profilesCache) { if(m_profilesCache.TryGetValue(targetID, out uce) && uce != null) { if(uce.classifiedsLists != null) { foreach(KeyValuePair<UUID,string> kvp in uce.classifiedsLists) { UUID kvpkey = kvp.Key; classifieds[kvpkey] = kvp.Value; lock (m_classifiedCache) { if (!m_classifiedCache.ContainsKey(kvpkey)) { m_classifiedCache.Add(kvpkey,targetID); m_classifiedInterest.Add(kvpkey, 0); } m_classifiedInterest[kvpkey]++; } } remoteClient.SendAvatarClassifiedReply(targetID, uce.classifiedsLists); return; } } } string serverURI = string.Empty; GetUserProfileServerURI(targetID, out serverURI); if(string.IsNullOrWhiteSpace(serverURI)) { remoteClient.SendAvatarClassifiedReply(targetID, classifieds); return; } OSDMap parameters= new OSDMap(); parameters.Add("creatorId", OSD.FromUUID(targetID)); OSD Params = (OSD)parameters; if(!rpc.JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString())) { remoteClient.SendAvatarClassifiedReply(targetID, classifieds); return; } parameters = (OSDMap)Params; if(!parameters.ContainsKey("result") || parameters["result"] == null) { remoteClient.SendAvatarClassifiedReply(targetID, classifieds); return; } OSDArray list = (OSDArray)parameters["result"]; foreach(OSD map in list) { OSDMap m = (OSDMap)map; UUID cid = m["classifieduuid"].AsUUID(); string name = m["name"].AsString(); classifieds[cid] = name; lock (m_classifiedCache) { if (!m_classifiedCache.ContainsKey(cid)) { m_classifiedCache.Add(cid,targetID); m_classifiedInterest.Add(cid, 0); } m_classifiedInterest[cid]++; } } lock(m_profilesCache) { if(!m_profilesCache.TryGetValue(targetID, out uce) || uce == null) uce = new UserProfileCacheEntry(); uce.classifiedsLists = classifieds; m_profilesCache.AddOrUpdate(targetID, uce, PROFILECACHEEXPIRE); } remoteClient.SendAvatarClassifiedReply(targetID, classifieds); }
public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) { if (String.IsNullOrEmpty(avatarID.ToString()) || String.IsNullOrEmpty(remoteClient.AgentId.ToString())) { // Looking for a reason that some viewers are sending null Id's m_log.DebugFormat("[PROFILES]: This should not happen remoteClient.AgentId {0} - avatarID {1}", remoteClient.AgentId, avatarID); return; } ScenePresence p = FindPresence(avatarID); if (p != null && p.isNPC) { remoteClient.SendAvatarProperties(avatarID, ((INPC)(p.ControllingClient)).profileAbout, ((INPC)(p.ControllingClient)).Born, Utils.StringToBytes("Non Player Character (NPC)"), "NPCs have no life", 0x10, UUID.Zero, ((INPC)(p.ControllingClient)).profileImage, "", UUID.Zero); remoteClient.SendAvatarInterestsReply(avatarID, 0, "", 0, "Getting into trouble", "Droidspeak"); return; } UserProfileProperties props; UserProfileCacheEntry uce = null; lock(m_profilesCache) { if(m_profilesCache.TryGetValue(avatarID, out uce) && uce != null) { if(uce.props != null) { props = uce.props; uint cflags = uce.flags; // if on same region force online if(p != null && !p.IsDeleted) cflags |= 0x10; remoteClient.SendAvatarProperties(props.UserId, props.AboutText, uce.born, uce.membershipType , props.FirstLifeText, cflags, props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask, props.SkillsText, props.Language); return; } else { if(uce.ClientsWaitingProps == null) uce.ClientsWaitingProps = new HashSet<IClientAPI>(); else if(uce.ClientsWaitingProps.Contains(remoteClient)) return; uce.ClientsWaitingProps.Add(remoteClient); } } else { uce = new UserProfileCacheEntry(); uce.ClientsWaitingProps = new HashSet<IClientAPI>(); uce.ClientsWaitingProps.Add(remoteClient); m_profilesCache.AddOrUpdate(avatarID, uce, PROFILECACHEEXPIRE); } } string serverURI = string.Empty; bool foreign = GetUserProfileServerURI(avatarID, out serverURI); UserAccount account = null; Dictionary<string,object> userInfo; if (!foreign) { account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, avatarID); } else { userInfo = new Dictionary<string, object>(); } Byte[] membershipType = new Byte[1]; string born = string.Empty; uint flags = 0x00; if (null != account) { if (account.UserTitle == "") membershipType[0] = (Byte)((account.UserFlags & 0xf00) >> 8); else membershipType = Utils.StringToBytes(account.UserTitle); born = Util.ToDateTime(account.Created).ToString( "M/d/yyyy", CultureInfo.InvariantCulture); flags = (uint)(account.UserFlags & 0xff); } else { if (GetUserAccountData(avatarID, out userInfo) == true) { if ((string)userInfo["user_title"] == "") membershipType[0] = (Byte)(((Byte)userInfo["user_flags"] & 0xf00) >> 8); else membershipType = Utils.StringToBytes((string)userInfo["user_title"]); int val_born = (int)userInfo["user_created"]; if(val_born != 0) born = Util.ToDateTime(val_born).ToString( "M/d/yyyy", CultureInfo.InvariantCulture); // picky, picky int val_flags = (int)userInfo["user_flags"]; flags = (uint)(val_flags & 0xff); } } props = new UserProfileProperties(); props.UserId = avatarID; string result = string.Empty; if(!GetProfileData(ref props, foreign, serverURI, out result)) { props.AboutText ="Profile not available at this time. User may still be unknown to this grid"; } if(!m_allowUserProfileWebURLs) props.WebUrl =""; HashSet<IClientAPI> clients; lock(m_profilesCache) { if(!m_profilesCache.TryGetValue(props.UserId, out uce) || uce == null) uce = new UserProfileCacheEntry(); uce.props = props; uce.born = born; uce.membershipType = membershipType; uce.flags = flags; clients = uce.ClientsWaitingProps; uce.ClientsWaitingProps = null; m_profilesCache.AddOrUpdate(props.UserId, uce, PROFILECACHEEXPIRE); } // if on same region force online if(p != null && !p.IsDeleted) flags |= 0x10; if(clients == null) { remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, membershipType , props.FirstLifeText, flags, props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask, props.SkillsText, props.Language); } else { if(!clients.Contains(remoteClient)) clients.Add(remoteClient); foreach(IClientAPI cli in clients) { if(!cli.IsActive) continue; cli.SendAvatarProperties(props.UserId, props.AboutText, born, membershipType , props.FirstLifeText, flags, props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); cli.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask, props.SkillsText, props.Language); } } }