several changes to llIsFriend and related methods

This commit is contained in:
UbitUmarov 2024-02-16 20:14:06 +00:00
parent 089037c749
commit cf27093ee9
7 changed files with 118 additions and 32 deletions

View File

@ -207,7 +207,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (!m_Enabled) if (!m_Enabled)
return; return;
// m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); //m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
m_Scenes.Add(scene); m_Scenes.Add(scene);
scene.RegisterModuleInterface<IFriendsModule>(this); scene.RegisterModuleInterface<IFriendsModule>(this);
@ -254,6 +254,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return 0; return 0;
} }
public bool IsFriend(UUID principalID, UUID friendID)
{
FriendInfo[] friends = GetFriendsFromCache(principalID);
if (friends.Length > 0)
{
FriendInfo finfo = GetFriend(friends, friendID);
return (finfo is not null && finfo.TheirFlags != -1);
}
return false;
}
public bool IsFriendOnline(UUID userID, UUID friendID) public bool IsFriendOnline(UUID userID, UUID friendID)
{ {
if(m_OnlineFriendsCache.TryGetValue(userID, out HashSet<UUID> friends)) if(m_OnlineFriendsCache.TryGetValue(userID, out HashSet<UUID> friends))

View File

@ -100,5 +100,6 @@ namespace OpenSim.Region.Framework.Interfaces
void CacheFriendsOnline(UUID userID, List<UUID> friendsOnline, bool online); void CacheFriendsOnline(UUID userID, List<UUID> friendsOnline, bool online);
void CacheFriendOnline(UUID userID, UUID friendOnline, bool online); void CacheFriendOnline(UUID userID, UUID friendOnline, bool online);
List<UUID> GetCachedFriendsOnline(UUID userID); List<UUID> GetCachedFriendsOnline(UUID userID);
bool IsFriend(UUID userID, UUID friendID);
} }
} }

View File

@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime; using System.Runtime;
using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Timers; using System.Timers;
@ -46,7 +47,6 @@ using Timer = System.Timers.Timer;
using TPFlags = OpenSim.Framework.Constants.TeleportFlags; using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
using GridRegion = OpenSim.Services.Interfaces.GridRegion; using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using PermissionMask = OpenSim.Framework.PermissionMask; using PermissionMask = OpenSim.Framework.PermissionMask;
using System.Runtime.CompilerServices;
namespace OpenSim.Region.Framework.Scenes namespace OpenSim.Region.Framework.Scenes
{ {
@ -463,7 +463,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// If true then updates are running. This may be true for a short period after a scene is de-activated. /// If true then updates are running. This may be true for a short period after a scene is de-activated.
/// </summary> /// </summary>
public bool IsRunning { get { return m_isRunning; } } public bool IsRunning
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return m_isRunning; }
}
private volatile bool m_isRunning; private volatile bool m_isRunning;
private bool m_firstHeartbeat = true; private bool m_firstHeartbeat = true;
@ -1193,6 +1197,7 @@ namespace OpenSim.Region.Framework.Scenes
/// TODO: Possibly stop other classes being able to manipulate this directly. /// TODO: Possibly stop other classes being able to manipulate this directly.
public SceneGraph SceneGraph public SceneGraph SceneGraph
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return m_sceneGraph; } get { return m_sceneGraph; }
} }
@ -5196,17 +5201,31 @@ Label_GroupsDone:
/// </summary> /// </summary>
/// <param name="agentID"></param> /// <param name="agentID"></param>
/// <returns>null if the presence was not found</returns> /// <returns>null if the presence was not found</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ScenePresence GetScenePresence(UUID agentID) public ScenePresence GetScenePresence(UUID agentID)
{ {
return m_sceneGraph.GetScenePresence(agentID); return m_sceneGraph.GetScenePresence(agentID);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool TryGetScenePresence(UUID agentID, out ScenePresence presence)
{
return m_sceneGraph.TryGetScenePresence(agentID, out presence);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetSceneRootPresence(UUID agentID, out ScenePresence presence)
{
return m_sceneGraph.TryGetSceneRootPresence(agentID, out presence);
}
/// <summary> /// <summary>
/// Request the scene presence by name. /// Request the scene presence by name.
/// </summary> /// </summary>
/// <param name="firstName"></param> /// <param name="firstName"></param>
/// <param name="lastName"></param> /// <param name="lastName"></param>
/// <returns>null if the presence was not found</returns> /// <returns>null if the presence was not found</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ScenePresence GetScenePresence(string firstName, string lastName) public ScenePresence GetScenePresence(string firstName, string lastName)
{ {
return m_sceneGraph.GetScenePresence(firstName, lastName); return m_sceneGraph.GetScenePresence(firstName, lastName);
@ -5217,6 +5236,7 @@ Label_GroupsDone:
/// </summary> /// </summary>
/// <param name="localID"></param> /// <param name="localID"></param>
/// <returns>null if the presence was not found</returns> /// <returns>null if the presence was not found</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ScenePresence GetScenePresence(uint localID) public ScenePresence GetScenePresence(uint localID)
{ {
return m_sceneGraph.GetScenePresence(localID); return m_sceneGraph.GetScenePresence(localID);
@ -5235,6 +5255,7 @@ Label_GroupsDone:
/// The shared list of the scene presences. /// The shared list of the scene presences.
/// </returns> /// </returns>
/// WARNING DO NOT MODIFY RETURNED VALUE /// WARNING DO NOT MODIFY RETURNED VALUE
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public List<ScenePresence> GetScenePresences() public List<ScenePresence> GetScenePresences()
{ {
//return new List<ScenePresence>(m_sceneGraph.GetScenePresences()); //return new List<ScenePresence>(m_sceneGraph.GetScenePresences());
@ -5246,6 +5267,7 @@ Label_GroupsDone:
/// Avatars may be an NPC or a 'real' client. /// Avatars may be an NPC or a 'real' client.
/// </summary> /// </summary>
/// <param name="action"></param> /// <param name="action"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ForEachRootScenePresence(Action<ScenePresence> action) public void ForEachRootScenePresence(Action<ScenePresence> action)
{ {
m_sceneGraph.ForEachRootScenePresence(action); m_sceneGraph.ForEachRootScenePresence(action);
@ -5255,6 +5277,7 @@ Label_GroupsDone:
/// Performs action on all scene presences (root and child) /// Performs action on all scene presences (root and child)
/// </summary> /// </summary>
/// <param name="action"></param> /// <param name="action"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ForEachScenePresence(Action<ScenePresence> action) public void ForEachScenePresence(Action<ScenePresence> action)
{ {
m_sceneGraph.ForEachScenePresence(action); m_sceneGraph.ForEachScenePresence(action);
@ -5266,6 +5289,7 @@ Label_GroupsDone:
/// <returns> /// <returns>
/// The scene object groups. If the scene is empty then an empty list is returned. /// The scene object groups. If the scene is empty then an empty list is returned.
/// </returns> /// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public List<SceneObjectGroup> GetSceneObjectGroups() public List<SceneObjectGroup> GetSceneObjectGroups()
{ {
return m_sceneGraph.GetSceneObjectGroups(); return m_sceneGraph.GetSceneObjectGroups();
@ -5276,6 +5300,7 @@ Label_GroupsDone:
/// </summary> /// </summary>
/// <param name="fullID"></param> /// <param name="fullID"></param>
/// <returns>null if no group with that id exists</returns> /// <returns>null if no group with that id exists</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SceneObjectGroup GetSceneObjectGroup(UUID fullID) public SceneObjectGroup GetSceneObjectGroup(UUID fullID)
{ {
return m_sceneGraph.GetSceneObjectGroup(fullID); return m_sceneGraph.GetSceneObjectGroup(fullID);
@ -5287,6 +5312,7 @@ Label_GroupsDone:
/// <remarks>This will only return a group if the local ID matches a root part</remarks> /// <remarks>This will only return a group if the local ID matches a root part</remarks>
/// <param name="localID"></param> /// <param name="localID"></param>
/// <returns>null if no group with that id exists</returns> /// <returns>null if no group with that id exists</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SceneObjectGroup GetSceneObjectGroup(uint localID) public SceneObjectGroup GetSceneObjectGroup(uint localID)
{ {
return m_sceneGraph.GetSceneObjectGroup(localID); return m_sceneGraph.GetSceneObjectGroup(localID);
@ -5298,6 +5324,7 @@ Label_GroupsDone:
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <returns>null if no group with that name exists</returns> /// <returns>null if no group with that name exists</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SceneObjectGroup GetSceneObjectGroup(string name) public SceneObjectGroup GetSceneObjectGroup(string name)
{ {
return m_sceneGraph.GetSceneObjectGroup(name); return m_sceneGraph.GetSceneObjectGroup(name);
@ -5309,6 +5336,7 @@ Label_GroupsDone:
/// <param name="fullID"></param> /// <param name="fullID"></param>
/// <param name="sog"></param> /// <param name="sog"></param>
/// <returns></returns> /// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog) public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
{ {
sog = GetSceneObjectGroup(fullID); sog = GetSceneObjectGroup(fullID);
@ -5321,6 +5349,7 @@ Label_GroupsDone:
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <returns></returns> /// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SceneObjectPart GetSceneObjectPart(string name) public SceneObjectPart GetSceneObjectPart(string name)
{ {
return m_sceneGraph.GetSceneObjectPart(name); return m_sceneGraph.GetSceneObjectPart(name);
@ -5331,6 +5360,7 @@ Label_GroupsDone:
/// </summary> /// </summary>
/// <param name="localID"></param> /// <param name="localID"></param>
/// <returns></returns> /// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SceneObjectPart GetSceneObjectPart(uint localID) public SceneObjectPart GetSceneObjectPart(uint localID)
{ {
return m_sceneGraph.GetSceneObjectPart(localID); return m_sceneGraph.GetSceneObjectPart(localID);
@ -5341,6 +5371,7 @@ Label_GroupsDone:
/// </summary> /// </summary>
/// <param name="fullID"></param> /// <param name="fullID"></param>
/// <returns></returns> /// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SceneObjectPart GetSceneObjectPart(UUID fullID) public SceneObjectPart GetSceneObjectPart(UUID fullID)
{ {
return m_sceneGraph.GetSceneObjectPart(fullID); return m_sceneGraph.GetSceneObjectPart(fullID);
@ -5352,6 +5383,7 @@ Label_GroupsDone:
/// <param name="fullID"></param> /// <param name="fullID"></param>
/// <param name="sop"></param> /// <param name="sop"></param>
/// <returns></returns> /// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop) public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
{ {
return m_sceneGraph.TryGetSceneObjectPart(fullID, out sop); return m_sceneGraph.TryGetSceneObjectPart(fullID, out sop);
@ -5362,6 +5394,7 @@ Label_GroupsDone:
/// </summary> /// </summary>
/// <param name="localID"></param> /// <param name="localID"></param>
/// <returns>null if no scene object group containing that prim is found</returns> /// <returns>null if no scene object group containing that prim is found</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SceneObjectGroup GetGroupByPrim(uint localID) public SceneObjectGroup GetGroupByPrim(uint localID)
{ {
return m_sceneGraph.GetGroupByPrim(localID); return m_sceneGraph.GetGroupByPrim(localID);
@ -5372,16 +5405,13 @@ Label_GroupsDone:
/// </summary> /// </summary>
/// <param name="fullID"></param> /// <param name="fullID"></param>
/// <returns>null if no scene object group containing that prim is found</returns> /// <returns>null if no scene object group containing that prim is found</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SceneObjectGroup GetGroupByPrim(UUID fullID) public SceneObjectGroup GetGroupByPrim(UUID fullID)
{ {
return m_sceneGraph.GetGroupByPrim(fullID); return m_sceneGraph.GetGroupByPrim(fullID);
} }
public override bool TryGetScenePresence(UUID agentID, out ScenePresence sp) [MethodImpl(MethodImplOptions.AggressiveInlining)]
{
return m_sceneGraph.TryGetScenePresence(agentID, out sp);
}
public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
{ {
return m_sceneGraph.TryGetAvatarByName(avatarName, out avatar); return m_sceneGraph.TryGetAvatarByName(avatarName, out avatar);
@ -5391,6 +5421,7 @@ Label_GroupsDone:
/// Perform an action on all clients with an avatar in this scene (root only) /// Perform an action on all clients with an avatar in this scene (root only)
/// </summary> /// </summary>
/// <param name="action"></param> /// <param name="action"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ForEachRootClient(Action<IClientAPI> action) public void ForEachRootClient(Action<IClientAPI> action)
{ {
ForEachRootScenePresence(delegate(ScenePresence presence) ForEachRootScenePresence(delegate(ScenePresence presence)
@ -5403,26 +5434,31 @@ Label_GroupsDone:
/// Perform an action on all clients connected to the region (root and child) /// Perform an action on all clients connected to the region (root and child)
/// </summary> /// </summary>
/// <param name="action"></param> /// <param name="action"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ForEachClient(Action<IClientAPI> action) public void ForEachClient(Action<IClientAPI> action)
{ {
m_clientManager.ForEach(action); m_clientManager.ForEach(action);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetNumberOfClients() public int GetNumberOfClients()
{ {
return m_clientManager.Count; return m_clientManager.Count;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetClient(UUID avatarID, out IClientAPI client) public bool TryGetClient(UUID avatarID, out IClientAPI client)
{ {
return m_clientManager.TryGetValue(avatarID, out client); return m_clientManager.TryGetValue(avatarID, out client);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetClient(System.Net.IPEndPoint remoteEndPoint, out IClientAPI client) public bool TryGetClient(System.Net.IPEndPoint remoteEndPoint, out IClientAPI client)
{ {
return m_clientManager.TryGetValue(remoteEndPoint, out client); return m_clientManager.TryGetValue(remoteEndPoint, out client);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ForEachSOG(Action<SceneObjectGroup> action) public void ForEachSOG(Action<SceneObjectGroup> action)
{ {
m_sceneGraph.ForEachSOG(action); m_sceneGraph.ForEachSOG(action);
@ -5433,6 +5469,7 @@ Label_GroupsDone:
/// will not affect the original list of objects in the scene. /// will not affect the original list of objects in the scene.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EntityBase[] GetEntities() public EntityBase[] GetEntities()
{ {
return m_sceneGraph.GetEntities(); return m_sceneGraph.GetEntities();
@ -5441,15 +5478,15 @@ Label_GroupsDone:
#endregion #endregion
// Commented pending deletion since this method no longer appears to do anything at all // Commented pending deletion since this method no longer appears to do anything at all
// public bool NeedSceneCacheClear(UUID agentID) // public bool NeedSceneCacheClear(UUID agentID)
// { // {
// IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>(); // IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
// if (inv is null) // if (inv is null)
// return true; // return true;
// //
// return inv.NeedSceneCacheClear(agentID, this); // return inv.NeedSceneCacheClear(agentID, this);
// } // }
public void CleanTempObjects() public void CleanTempObjects()
{ {
@ -5473,6 +5510,7 @@ Label_GroupsDone:
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DeleteFromStorage(UUID uuid) public void DeleteFromStorage(UUID uuid)
{ {
SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID); SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID);
@ -5566,12 +5604,14 @@ Environment.Exit(1);
// Get terrain height at the specified <x,y> location. // Get terrain height at the specified <x,y> location.
// Presumes the underlying implementation is a heightmap which is a 1m grid. // Presumes the underlying implementation is a heightmap which is a 1m grid.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float GetGroundHeight(float x, float y) public float GetGroundHeight(float x, float y)
{ {
return Heightmap.GetHeight(x, y); return Heightmap.GetHeight(x, y);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void CheckHeartbeat() private void CheckHeartbeat()
{ {
if (m_firstHeartbeat) if (m_firstHeartbeat)
@ -5581,6 +5621,7 @@ Environment.Exit(1);
Start(); Start();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override ISceneObject DeserializeObject(string representation) public override ISceneObject DeserializeObject(string representation)
{ {
return SceneObjectSerializer.FromXml2Format(representation); return SceneObjectSerializer.FromXml2Format(representation);
@ -5588,9 +5629,11 @@ Environment.Exit(1);
public override bool AllowScriptCrossings public override bool AllowScriptCrossings
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return m_allowScriptCrossings; } get { return m_allowScriptCrossings; }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 GetNearestAllowedPosition(ScenePresence avatar) public Vector3 GetNearestAllowedPosition(ScenePresence avatar)
{ {
return GetNearestAllowedPosition(avatar, null); return GetNearestAllowedPosition(avatar, null);
@ -5638,12 +5681,14 @@ Environment.Exit(1);
return nearestRegionEdgePoint; return nearestRegionEdgePoint;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Vector3 GetParcelCenterAtGround(ILandObject parcel) private Vector3 GetParcelCenterAtGround(ILandObject parcel)
{ {
Vector2 center = parcel.CenterPoint; Vector2 center = parcel.CenterPoint;
return GetPositionAtGround(center.X, center.Y); return GetPositionAtGround(center.X, center.Y);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y) public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y)
{ {
return GetNearestAllowedParcel(avatarId, x, y, null); return GetNearestAllowedParcel(avatarId, x, y, null);
@ -5683,6 +5728,7 @@ Environment.Exit(1);
return nearestParcel; return nearestParcel;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector2 GetParcelSafeCorner(ILandObject parcel) private static Vector2 GetParcelSafeCorner(ILandObject parcel)
{ {
Vector2 place = parcel.StartPoint; Vector2 place = parcel.StartPoint;
@ -5736,6 +5782,7 @@ Environment.Exit(1);
return ground; return ground;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Vector3 GetPositionAtGround(float x, float y) private Vector3 GetPositionAtGround(float x, float y)
{ {
return new Vector3(x, y, GetGroundHeight(x, y)); return new Vector3(x, y, GetGroundHeight(x, y));

View File

@ -496,11 +496,10 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>null if there is no registered module implementing that interface</returns> /// <returns>null if there is no registered module implementing that interface</returns>
public T RequestModuleInterface<T>() public T RequestModuleInterface<T>()
{ {
if (ModuleInterfaces.ContainsKey(typeof(T)) && if (ModuleInterfaces.TryGetValue(typeof(T), out List<object> mio ) && mio.Count > 0)
(ModuleInterfaces[typeof(T)].Count > 0)) return (T)mio[0];
return (T)ModuleInterfaces[typeof(T)][0];
else return default;
return default(T);
} }
/// <summary> /// <summary>

View File

@ -1042,6 +1042,32 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
protected internal bool TryGetSceneRootPresence(UUID agentID, out ScenePresence avatar)
{
bool entered = false;
try
{
try { }
finally
{
m_scenePresencesLock.EnterReadLock();
entered = true;
}
return m_scenePresenceMap.TryGetValue(agentID, out avatar) && !avatar.IsChildAgent;
}
catch
{
avatar = null;
return false;
}
finally
{
if (entered)
m_scenePresencesLock.ExitReadLock();
}
}
protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar)
{ {
List<ScenePresence> presences = GetScenePresences(); List<ScenePresence> presences = GetScenePresences();

View File

@ -18513,7 +18513,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (string.IsNullOrEmpty(pattern.m_string)) if (string.IsNullOrEmpty(pattern.m_string))
return src; return src;
Regex rx = new(pattern, RegexOptions, new TimeSpan(500000)); // 50ms) Regex rx = new(pattern, RegexOptions, TimeSpan.FromMilliseconds(10));
if (replacement == null) if (replacement == null)
return rx.Replace(src.m_string, string.Empty, count); return rx.Replace(src.m_string, string.Empty, count);
@ -18723,18 +18723,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (parentsog.OwnerID.Equals(parentsog.GroupID)) if (parentsog.OwnerID.Equals(parentsog.GroupID))
return llSameGroup(agent_id); return llSameGroup(agent_id);
if (!UUID.TryParse(agent_id, out UUID agent) || agent.IsZero())
return 0;
IFriendsModule fm = World.RequestModuleInterface<IFriendsModule>(); IFriendsModule fm = World.RequestModuleInterface<IFriendsModule>();
if(fm is null) if(fm is null)
return 0; return 0;
if (World.GetScenePresence(parentsog.OwnerID) is null) if (World.TryGetSceneRootPresence(agent, out _))
return 0; return fm.IsFriend(agent, parentsog.OwnerID) ? 1 : 0;
if (!UUID.TryParse(agent_id, out UUID agent))
return 0;
if (World.GetScenePresence(agent) is null)
return 0;
return fm.IsFriendOnline(parentsog.OwnerID, agent) ? 1 : 0; if (World.TryGetSceneRootPresence(parentsog.OwnerID, out _))
return fm.IsFriend(parentsog.OwnerID, agent) ? 1 : 0;
return 0;
} }
} }

View File

@ -2778,7 +2778,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{ {
return m_LSL_Functions.llLinksetDataListKeys(start, count); return m_LSL_Functions.llLinksetDataListKeys(start, count);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public LSL_List llLinksetDataFindKeys(LSL_String pattern, LSL_Integer start, LSL_Integer count) public LSL_List llLinksetDataFindKeys(LSL_String pattern, LSL_Integer start, LSL_Integer count)
{ {