diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index a0ed5a5274..c532d0d645 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -56,6 +56,9 @@ namespace OpenSim.Region.CoreModules.World.Land protected List primsOverMe = new List(); protected Dictionary m_listTransactions = new Dictionary(); + protected ExpiringCache m_groupMemberCache = new ExpiringCache(); + protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds + public bool[,] LandBitmap { get { return m_landBitmap; } @@ -417,6 +420,48 @@ namespace OpenSim.Region.CoreModules.World.Land return false; } + public bool HasGroupAccess(UUID avatar) + { + if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) + { + ScenePresence sp; + if (!m_scene.TryGetScenePresence(avatar, out sp)) + { + bool isMember; + if (m_groupMemberCache.TryGetValue(avatar, out isMember)) + return isMember; + + IGroupsModule groupsModule = m_scene.RequestModuleInterface(); + if (groupsModule == null) + return false; + + GroupMembershipData[] membership = groupsModule.GetMembershipData(avatar); + if (membership == null || membership.Length == 0) + { + m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); + return false; + } + + foreach (GroupMembershipData d in membership) + { + if (d.GroupID == LandData.GroupID) + { + m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); + return true; + } + } + m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); + return false; + } + + if (!sp.ControllingClient.IsGroupMember(LandData.GroupID)) + return false; + + return true; + } + return false; + } + public bool IsBannedFromLand(UUID avatar) { ExpireAccessList(); @@ -448,6 +493,9 @@ namespace OpenSim.Region.CoreModules.World.Land public bool IsRestrictedFromLand(UUID avatar) { + if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0) + return false; + if (m_scene.Permissions.IsAdministrator(avatar)) return false; @@ -457,10 +505,10 @@ namespace OpenSim.Region.CoreModules.World.Land if (avatar == LandData.OwnerID) return false; - if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0) + if (HasGroupAccess(avatar)) return false; - return (!IsInLandAccessList(avatar)); + return !IsInLandAccessList(avatar); } public bool IsInLandAccessList(UUID avatar)