diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index a0ed5a5274..ced7b523b2 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,45 @@ 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, true, m_groupMemberCacheTimeout); + return true; + } + } + m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); + return false; + } + + return sp.ControllingClient.IsGroupMember(LandData.GroupID); + } + return false; + } + public bool IsBannedFromLand(UUID avatar) { ExpireAccessList(); @@ -448,6 +490,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 +502,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) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 2a15e5d6f6..e669f4c74c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1294,7 +1294,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); - // Need to send a group membership update to the client // UDP version doesn't seem to behave nicely. But we're going to send it out here // with an empty group membership to hopefully remove groups being displayed due @@ -1305,6 +1304,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); + if (remoteClient.AgentId == dataForAgentID) + remoteClient.RefreshGroupMembership(); } ///