From cf27093ee9aaec140adf8f558b788e0e2af9cfe3 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 16 Feb 2024 20:14:06 +0000 Subject: [PATCH] several changes to llIsFriend and related methods --- .../Avatar/Friends/FriendsModule.cs | 13 ++- .../Framework/Interfaces/IFriendsModule.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.cs | 81 +++++++++++++++---- OpenSim/Region/Framework/Scenes/SceneBase.cs | 9 +-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 26 ++++++ .../Shared/Api/Implementation/LSL_Api.cs | 18 +++-- .../Shared/Api/Runtime/LSL_Stub.cs | 2 +- 7 files changed, 118 insertions(+), 32 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index dbc6a04ee4..d1c0d9738a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -207,7 +207,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (!m_Enabled) return; -// m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); + //m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); m_Scenes.Add(scene); scene.RegisterModuleInterface(this); @@ -254,6 +254,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends 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) { if(m_OnlineFriendsCache.TryGetValue(userID, out HashSet friends)) diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs index 5d14119f0f..8f6496a7c9 100644 --- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs @@ -100,5 +100,6 @@ namespace OpenSim.Region.Framework.Interfaces void CacheFriendsOnline(UUID userID, List friendsOnline, bool online); void CacheFriendOnline(UUID userID, UUID friendOnline, bool online); List GetCachedFriendsOnline(UUID userID); + bool IsFriend(UUID userID, UUID friendID); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index da3dfe44db..59a913769e 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Timers; @@ -46,7 +47,6 @@ using Timer = System.Timers.Timer; using TPFlags = OpenSim.Framework.Constants.TeleportFlags; using GridRegion = OpenSim.Services.Interfaces.GridRegion; using PermissionMask = OpenSim.Framework.PermissionMask; -using System.Runtime.CompilerServices; namespace OpenSim.Region.Framework.Scenes { @@ -463,7 +463,11 @@ namespace OpenSim.Region.Framework.Scenes /// /// If true then updates are running. This may be true for a short period after a scene is de-activated. /// - public bool IsRunning { get { return m_isRunning; } } + public bool IsRunning + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return m_isRunning; } + } private volatile bool m_isRunning; 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. public SceneGraph SceneGraph { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return m_sceneGraph; } } @@ -5196,17 +5201,31 @@ Label_GroupsDone: /// /// /// null if the presence was not found + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public ScenePresence GetScenePresence(UUID 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); + } /// /// Request the scene presence by name. /// /// /// /// null if the presence was not found + [MethodImpl(MethodImplOptions.AggressiveInlining)] public ScenePresence GetScenePresence(string firstName, string lastName) { return m_sceneGraph.GetScenePresence(firstName, lastName); @@ -5217,6 +5236,7 @@ Label_GroupsDone: /// /// /// null if the presence was not found + [MethodImpl(MethodImplOptions.AggressiveInlining)] public ScenePresence GetScenePresence(uint localID) { return m_sceneGraph.GetScenePresence(localID); @@ -5235,6 +5255,7 @@ Label_GroupsDone: /// The shared list of the scene presences. /// /// WARNING DO NOT MODIFY RETURNED VALUE + [MethodImpl(MethodImplOptions.AggressiveInlining)] public List GetScenePresences() { //return new List(m_sceneGraph.GetScenePresences()); @@ -5246,6 +5267,7 @@ Label_GroupsDone: /// Avatars may be an NPC or a 'real' client. /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ForEachRootScenePresence(Action action) { m_sceneGraph.ForEachRootScenePresence(action); @@ -5255,6 +5277,7 @@ Label_GroupsDone: /// Performs action on all scene presences (root and child) /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ForEachScenePresence(Action action) { m_sceneGraph.ForEachScenePresence(action); @@ -5266,6 +5289,7 @@ Label_GroupsDone: /// /// The scene object groups. If the scene is empty then an empty list is returned. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public List GetSceneObjectGroups() { return m_sceneGraph.GetSceneObjectGroups(); @@ -5276,6 +5300,7 @@ Label_GroupsDone: /// /// /// null if no group with that id exists + [MethodImpl(MethodImplOptions.AggressiveInlining)] public SceneObjectGroup GetSceneObjectGroup(UUID fullID) { return m_sceneGraph.GetSceneObjectGroup(fullID); @@ -5287,6 +5312,7 @@ Label_GroupsDone: /// This will only return a group if the local ID matches a root part /// /// null if no group with that id exists + [MethodImpl(MethodImplOptions.AggressiveInlining)] public SceneObjectGroup GetSceneObjectGroup(uint localID) { return m_sceneGraph.GetSceneObjectGroup(localID); @@ -5298,6 +5324,7 @@ Label_GroupsDone: /// /// /// null if no group with that name exists + [MethodImpl(MethodImplOptions.AggressiveInlining)] public SceneObjectGroup GetSceneObjectGroup(string name) { return m_sceneGraph.GetSceneObjectGroup(name); @@ -5309,6 +5336,7 @@ Label_GroupsDone: /// /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog) { sog = GetSceneObjectGroup(fullID); @@ -5321,6 +5349,7 @@ Label_GroupsDone: /// /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public SceneObjectPart GetSceneObjectPart(string name) { return m_sceneGraph.GetSceneObjectPart(name); @@ -5331,6 +5360,7 @@ Label_GroupsDone: /// /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public SceneObjectPart GetSceneObjectPart(uint localID) { return m_sceneGraph.GetSceneObjectPart(localID); @@ -5341,6 +5371,7 @@ Label_GroupsDone: /// /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public SceneObjectPart GetSceneObjectPart(UUID fullID) { return m_sceneGraph.GetSceneObjectPart(fullID); @@ -5352,6 +5383,7 @@ Label_GroupsDone: /// /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop) { return m_sceneGraph.TryGetSceneObjectPart(fullID, out sop); @@ -5362,6 +5394,7 @@ Label_GroupsDone: /// /// /// null if no scene object group containing that prim is found + [MethodImpl(MethodImplOptions.AggressiveInlining)] public SceneObjectGroup GetGroupByPrim(uint localID) { return m_sceneGraph.GetGroupByPrim(localID); @@ -5372,16 +5405,13 @@ Label_GroupsDone: /// /// /// null if no scene object group containing that prim is found + [MethodImpl(MethodImplOptions.AggressiveInlining)] public SceneObjectGroup GetGroupByPrim(UUID fullID) { return m_sceneGraph.GetGroupByPrim(fullID); } - public override bool TryGetScenePresence(UUID agentID, out ScenePresence sp) - { - return m_sceneGraph.TryGetScenePresence(agentID, out sp); - } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetAvatarByName(string avatarName, out ScenePresence 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) /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ForEachRootClient(Action action) { ForEachRootScenePresence(delegate(ScenePresence presence) @@ -5403,26 +5434,31 @@ Label_GroupsDone: /// Perform an action on all clients connected to the region (root and child) /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ForEachClient(Action action) { m_clientManager.ForEach(action); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetNumberOfClients() { return m_clientManager.Count; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetClient(UUID avatarID, out IClientAPI client) { return m_clientManager.TryGetValue(avatarID, out client); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetClient(System.Net.IPEndPoint remoteEndPoint, out IClientAPI client) { return m_clientManager.TryGetValue(remoteEndPoint, out client); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ForEachSOG(Action action) { m_sceneGraph.ForEachSOG(action); @@ -5433,6 +5469,7 @@ Label_GroupsDone: /// will not affect the original list of objects in the scene. /// /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public EntityBase[] GetEntities() { return m_sceneGraph.GetEntities(); @@ -5441,15 +5478,15 @@ Label_GroupsDone: #endregion -// Commented pending deletion since this method no longer appears to do anything at all -// public bool NeedSceneCacheClear(UUID agentID) -// { -// IInventoryTransferModule inv = RequestModuleInterface(); -// if (inv is null) -// return true; -// -// return inv.NeedSceneCacheClear(agentID, this); -// } + // Commented pending deletion since this method no longer appears to do anything at all + // public bool NeedSceneCacheClear(UUID agentID) + // { + // IInventoryTransferModule inv = RequestModuleInterface(); + // if (inv is null) + // return true; + // + // return inv.NeedSceneCacheClear(agentID, this); + // } public void CleanTempObjects() { @@ -5473,6 +5510,7 @@ Label_GroupsDone: } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DeleteFromStorage(UUID uuid) { SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID); @@ -5566,12 +5604,14 @@ Environment.Exit(1); // Get terrain height at the specified location. // Presumes the underlying implementation is a heightmap which is a 1m grid. - + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float GetGroundHeight(float x, float y) { return Heightmap.GetHeight(x, y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void CheckHeartbeat() { if (m_firstHeartbeat) @@ -5581,6 +5621,7 @@ Environment.Exit(1); Start(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override ISceneObject DeserializeObject(string representation) { return SceneObjectSerializer.FromXml2Format(representation); @@ -5588,9 +5629,11 @@ Environment.Exit(1); public override bool AllowScriptCrossings { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return m_allowScriptCrossings; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3 GetNearestAllowedPosition(ScenePresence avatar) { return GetNearestAllowedPosition(avatar, null); @@ -5638,12 +5681,14 @@ Environment.Exit(1); return nearestRegionEdgePoint; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private Vector3 GetParcelCenterAtGround(ILandObject parcel) { Vector2 center = parcel.CenterPoint; return GetPositionAtGround(center.X, center.Y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y) { return GetNearestAllowedParcel(avatarId, x, y, null); @@ -5683,6 +5728,7 @@ Environment.Exit(1); return nearestParcel; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector2 GetParcelSafeCorner(ILandObject parcel) { Vector2 place = parcel.StartPoint; @@ -5736,6 +5782,7 @@ Environment.Exit(1); return ground; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private Vector3 GetPositionAtGround(float x, float y) { return new Vector3(x, y, GetGroundHeight(x, y)); diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 62f4fe0962..46df46b8be 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -496,11 +496,10 @@ namespace OpenSim.Region.Framework.Scenes /// null if there is no registered module implementing that interface public T RequestModuleInterface() { - if (ModuleInterfaces.ContainsKey(typeof(T)) && - (ModuleInterfaces[typeof(T)].Count > 0)) - return (T)ModuleInterfaces[typeof(T)][0]; - else - return default(T); + if (ModuleInterfaces.TryGetValue(typeof(T), out List mio ) && mio.Count > 0) + return (T)mio[0]; + + return default; } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 228488faf1..b4a94dd5bd 100755 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -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) { List presences = GetScenePresences(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b835dcea3c..28ef8d3edf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -18513,7 +18513,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (string.IsNullOrEmpty(pattern.m_string)) return src; - Regex rx = new(pattern, RegexOptions, new TimeSpan(500000)); // 50ms) + Regex rx = new(pattern, RegexOptions, TimeSpan.FromMilliseconds(10)); if (replacement == null) 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)) return llSameGroup(agent_id); + if (!UUID.TryParse(agent_id, out UUID agent) || agent.IsZero()) + return 0; + IFriendsModule fm = World.RequestModuleInterface(); if(fm is null) return 0; - if (World.GetScenePresence(parentsog.OwnerID) is null) - return 0; - if (!UUID.TryParse(agent_id, out UUID agent)) - return 0; - if (World.GetScenePresence(agent) is null) - return 0; + if (World.TryGetSceneRootPresence(agent, out _)) + return fm.IsFriend(agent, parentsog.OwnerID) ? 1 : 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; } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index d8b0079e6e..f8bc0526bd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -2778,7 +2778,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_LSL_Functions.llLinksetDataListKeys(start, count); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public LSL_List llLinksetDataFindKeys(LSL_String pattern, LSL_Integer start, LSL_Integer count) {