mirror of
https://github.com/opensim/opensim.git
synced 2026-08-06 01:06:30 +08:00
try improve profiles online indication a bit more
This commit is contained in:
@@ -88,6 +88,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
/// </remarks>
|
||||
protected Dictionary<UUID, UserFriendData> m_Friends = new();
|
||||
|
||||
protected Dictionary<UUID, HashSet<UUID>> m_OnlineFriendsCache = new();
|
||||
|
||||
/// <summary>
|
||||
/// Maintain a record of clients that need to notify about their online status. This only
|
||||
/// needs to be done on login. Subsequent online/offline friend changes are sent by a different mechanism.
|
||||
@@ -241,15 +243,54 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
public virtual int GetRightsGrantedByFriend(UUID principalID, UUID friendID)
|
||||
{
|
||||
FriendInfo[] friends = GetFriendsFromCache(principalID);
|
||||
FriendInfo finfo = GetFriend(friends, friendID);
|
||||
if (finfo is not null && finfo.TheirFlags != -1)
|
||||
if (friends.Length > 0)
|
||||
{
|
||||
return finfo.TheirFlags;
|
||||
FriendInfo finfo = GetFriend(friends, friendID);
|
||||
if (finfo is not null && finfo.TheirFlags != -1)
|
||||
{
|
||||
return finfo.TheirFlags;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void OnMakeRootAgent(ScenePresence sp)
|
||||
public bool IsFriendOnline(UUID userID, UUID friendID)
|
||||
{
|
||||
if(m_OnlineFriendsCache.TryGetValue(userID, out HashSet<UUID> friends))
|
||||
return friends.Contains(friendID);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CacheFriendsOnline(UUID userID, List<UUID> friendsOnline, bool online)
|
||||
{
|
||||
if (!m_OnlineFriendsCache.TryGetValue(userID, out HashSet<UUID> friends))
|
||||
{
|
||||
friends = new HashSet<UUID>();
|
||||
m_OnlineFriendsCache[userID] = friends;
|
||||
}
|
||||
foreach (UUID friendID in friendsOnline)
|
||||
{
|
||||
if (online)
|
||||
friends.Add(friendID);
|
||||
else
|
||||
friends.Remove(friendID);
|
||||
}
|
||||
}
|
||||
|
||||
public void CacheFriendOnline(UUID userID, UUID friendID, bool online)
|
||||
{
|
||||
if (!m_OnlineFriendsCache.TryGetValue(userID, out HashSet<UUID> friends))
|
||||
{
|
||||
friends = new HashSet<UUID>();
|
||||
m_OnlineFriendsCache[userID] = friends;
|
||||
}
|
||||
if (online)
|
||||
friends.Add(friendID);
|
||||
else
|
||||
friends.Remove(friendID);
|
||||
}
|
||||
|
||||
private void OnMakeRootAgent(ScenePresence sp)
|
||||
{
|
||||
if(sp.m_gotCrossUpdate)
|
||||
return;
|
||||
@@ -333,6 +374,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
lock (m_Friends)
|
||||
{
|
||||
m_OnlineFriendsCache.Remove(agentID);
|
||||
if (m_Friends.TryGetValue(agentID, out UserFriendData friendsData))
|
||||
{
|
||||
friendsData.Refcount--;
|
||||
@@ -438,17 +480,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
List<UUID> GetOnlineFriends(UUID userID)
|
||||
{
|
||||
List<string> friendList = new();
|
||||
|
||||
List<UUID> online = new();
|
||||
FriendInfo[] friends = GetFriendsFromCache(userID);
|
||||
if(friends.Length == 0)
|
||||
return online;
|
||||
|
||||
List<string> friendList = new(friends.Length);
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
|
||||
friendList.Add(fi.Friend);
|
||||
}
|
||||
|
||||
List<UUID> online = new();
|
||||
|
||||
if (friendList.Count > 0)
|
||||
GetOnlineFriends(userID, friendList, online);
|
||||
|
||||
@@ -458,16 +501,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return online;
|
||||
}
|
||||
|
||||
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, List<UUID> online)
|
||||
{
|
||||
//m_log.DebugFormat(
|
||||
// "[FRIENDS MODULE]: Looking for online presence of {0} users for {1}", friendList.Count, userID);
|
||||
|
||||
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
||||
if(presence.Length == 0)
|
||||
return;
|
||||
|
||||
if (!m_OnlineFriendsCache.TryGetValue(userID, out HashSet<UUID> friends))
|
||||
{
|
||||
friends = new HashSet<UUID>();
|
||||
m_OnlineFriendsCache[userID] = friends;
|
||||
}
|
||||
|
||||
foreach (PresenceInfo pi in presence)
|
||||
{
|
||||
if (UUID.TryParse(pi.UserID, out UUID presenceID))
|
||||
{
|
||||
online.Add(presenceID);
|
||||
friends.Add(presenceID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,6 +1017,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
IClientAPI friendClient = LocateClientObject(friendID);
|
||||
if (friendClient is not null)
|
||||
{
|
||||
CacheFriendOnline(friendID, userID, online);
|
||||
// the friend in this sim as root agent
|
||||
if (online)
|
||||
friendClient.SendAgentOnline(new UUID[] { userID });
|
||||
@@ -1001,7 +1057,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
lock (m_Friends)
|
||||
{
|
||||
FriendInfo[] friends = GetFriendsFromCache(friendID);
|
||||
if(friends != EMPTY_FRIENDS)
|
||||
if(friends.Length > 0)
|
||||
{
|
||||
FriendInfo finfo = GetFriend(friends, userID);
|
||||
if(finfo is not null)
|
||||
@@ -1019,11 +1075,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
|
||||
// is on the critical path for transferring an avatar from one region to another.
|
||||
UUID agentID = client.AgentId;
|
||||
lock (m_Friends)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||
if (m_Friends.TryGetValue(client.AgentId, out UserFriendData friendsData))
|
||||
friendsData.Friends = GetFriendsFromService(client);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
public void Notify(UUID userID, Dictionary<string, List<FriendInfo>> friendsPerDomain, bool online)
|
||||
{
|
||||
if(m_FriendsModule is null)
|
||||
return;
|
||||
|
||||
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
|
||||
{
|
||||
// For the others, call the user agent service
|
||||
@@ -51,10 +54,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
List<UUID> friendsOnline = fConn.StatusNotification(ids, userID, online);
|
||||
|
||||
if (online && friendsOnline.Count > 0)
|
||||
if (friendsOnline.Count > 0)
|
||||
{
|
||||
IClientAPI client = m_FriendsModule.LocateClientObject(userID);
|
||||
client?.SendAgentOnline(friendsOnline.ToArray());
|
||||
if(client is not null)
|
||||
{
|
||||
m_FriendsModule.CacheFriendsOnline(userID, friendsOnline, online);
|
||||
if(online)
|
||||
client?.SendAgentOnline(friendsOnline.ToArray());
|
||||
else
|
||||
client?.SendAgentOffline(friendsOnline.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
m_profilesCache.AddOrUpdate(props.UserId, uce, PROFILECACHEEXPIRE);
|
||||
}
|
||||
|
||||
if (IsFriendOnline(req.client.AgentId, req.agent))
|
||||
if (IsFriendOnline(req.client, req.agent))
|
||||
flags |= (uint)ProfileFlags.Online;
|
||||
else
|
||||
flags &= (uint)~ProfileFlags.Online;
|
||||
@@ -1086,9 +1086,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
{
|
||||
//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);
|
||||
UserProfilePick pick = new();
|
||||
GetUserProfileServerURI(remoteClient.AgentId, out string serverURI);
|
||||
if(string.IsNullOrWhiteSpace(serverURI))
|
||||
return;
|
||||
|
||||
@@ -1192,10 +1191,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
{
|
||||
if(m_profilesCache.TryGetValue(remoteClient.AgentId, out uce) && uce is not null)
|
||||
{
|
||||
if(uce.picks != null && uce.picks.ContainsKey(queryPickID))
|
||||
uce.picks.Remove(queryPickID);
|
||||
if(uce.picksList is not null)
|
||||
uce.picksList.Remove(queryPickID);
|
||||
uce.picks?.Remove(queryPickID);
|
||||
uce.picksList?.Remove(queryPickID);
|
||||
m_profilesCache.AddOrUpdate(remoteClient.AgentId, uce, PROFILECACHEEXPIRE);
|
||||
}
|
||||
}
|
||||
@@ -1451,7 +1448,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
props = uce.props;
|
||||
uint cflags = uce.flags;
|
||||
|
||||
if (IsFriendOnline(remoteClient.AgentId, avatarID))
|
||||
if (IsFriendOnline(remoteClient, avatarID))
|
||||
cflags = (uint)ProfileFlags.Online;
|
||||
else
|
||||
cflags &= (uint)~ProfileFlags.Online;
|
||||
@@ -1831,22 +1828,21 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual bool IsFriendOnline(UUID client, UUID agent)
|
||||
public virtual bool IsFriendOnline(IClientAPI client, UUID agent)
|
||||
{
|
||||
// if on same region force online
|
||||
// if on same region force online
|
||||
ScenePresence p = Scene.GetScenePresence(agent);
|
||||
if (p is not null && !p.IsDeleted)
|
||||
if (p is not null && !p.IsChildAgent && !p.IsDeleted)
|
||||
return true;
|
||||
|
||||
IFriendsModule friendsModule = Scene.RequestModuleInterface<IFriendsModule>();
|
||||
if (friendsModule is not null)
|
||||
if (friendsModule is not null && friendsModule.IsFriendOnline(client.AgentId, agent))
|
||||
return true;
|
||||
|
||||
if(client.SceneAgent is ScenePresence sp && sp.IsViewerUIGod)
|
||||
{
|
||||
int friendPerms = friendsModule.GetRightsGrantedByFriend(client, agent);
|
||||
if((friendPerms & (int)FriendRights.CanSeeOnline) != 0)
|
||||
{
|
||||
Services.Interfaces.PresenceInfo[] pi = Scene.PresenceService?.GetAgents(new string[] { agent.ToString() });
|
||||
return pi is not null && pi.Length > 0;
|
||||
}
|
||||
Services.Interfaces.PresenceInfo[] pi = Scene.PresenceService?.GetAgents(new string[] { agent.ToString() });
|
||||
return pi != null && pi.Length > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -96,5 +96,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
|
||||
void IsNowRoot(ScenePresence sp);
|
||||
bool SendFriendsOnlineIfNeeded(IClientAPI client);
|
||||
bool IsFriendOnline(UUID userID, UUID friendID);
|
||||
void CacheFriendsOnline(UUID userID, List<UUID> friendsOnline, bool online);
|
||||
void CacheFriendOnline(UUID userID, UUID friendOnline, bool online);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user