Simplify group access checks and break them out into a separate method.

Use existing cache if the avatar is within the region and use an
ExpiringCache to cache status if the avatar is not in the region. The
30 second delay now applies to scripted objects ony and only when the owner
is not present.
integration
Melanie 2012-04-05 00:45:58 +01:00
parent 36c8fa16c0
commit a5d6b624f6
1 changed files with 49 additions and 57 deletions

View File

@ -56,11 +56,8 @@ namespace OpenSim.Region.CoreModules.World.Land
protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
protected IGroupsModule m_groupsModule; protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>();
protected const uint PARCEL_FLAG_USE_ACCESS_GROUP = 0x100; // parcel limits access to a group protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds
protected Dictionary<UUID, long> m_isGroupMemberCache = new Dictionary<UUID, long>();
protected Dictionary<UUID, long> m_notGroupMemberCache = new Dictionary<UUID, long>();
protected const long m_groupMemberCacheTimeout = 30; // cache invalidation after 30 seconds
public bool[,] LandBitmap public bool[,] LandBitmap
{ {
@ -138,8 +135,6 @@ namespace OpenSim.Region.CoreModules.World.Land
else else
LandData.GroupID = UUID.Zero; LandData.GroupID = UUID.Zero;
LandData.IsGroupOwned = is_group_owned; LandData.IsGroupOwned = is_group_owned;
m_groupsModule = scene.RequestModuleInterface<IGroupsModule>();
} }
#endregion #endregion
@ -425,6 +420,48 @@ namespace OpenSim.Region.CoreModules.World.Land
return false; 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<IGroupsModule>();
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) public bool IsBannedFromLand(UUID avatar)
{ {
ExpireAccessList(); ExpireAccessList();
@ -456,6 +493,9 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool IsRestrictedFromLand(UUID avatar) public bool IsRestrictedFromLand(UUID avatar)
{ {
if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0)
return false;
if (m_scene.Permissions.IsAdministrator(avatar)) if (m_scene.Permissions.IsAdministrator(avatar))
return false; return false;
@ -465,58 +505,10 @@ namespace OpenSim.Region.CoreModules.World.Land
if (avatar == LandData.OwnerID) if (avatar == LandData.OwnerID)
return false; return false;
if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0) if (HasGroupAccess(avatar))
return false; return false;
if (IsInLandAccessList(avatar)) return !IsInLandAccessList(avatar);
return false;
UUID groupID = LandData.GroupID;
if ((m_groupsModule != null) && (groupID != UUID.Zero) && ((LandData.Flags & PARCEL_FLAG_USE_ACCESS_GROUP) == PARCEL_FLAG_USE_ACCESS_GROUP))
{
long now = Util.UnixTimeSinceEpoch();
if (m_isGroupMemberCache.ContainsKey(avatar))
{
if (now - m_isGroupMemberCache[avatar] <= m_groupMemberCacheTimeout) // invalid?
{
m_isGroupMemberCache[avatar] = now;
return false;
}
else
m_isGroupMemberCache.Remove(avatar);
}
if (m_notGroupMemberCache.ContainsKey(avatar))
{
if (now - m_notGroupMemberCache[avatar] <= m_groupMemberCacheTimeout) // invalid?
{
// m_notGroupMemberCache[avatar] = now;
return true;
}
else
m_notGroupMemberCache.Remove(avatar);
}
GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(avatar);
if (GroupMembership != null)
{
for (int i = 0; i < GroupMembership.Length; i++)
{
if (groupID == GroupMembership[i].GroupID)
{
m_isGroupMemberCache[avatar] = now;
return false;
}
}
}
m_notGroupMemberCache[avatar] = now;
}
return true;
} }
public bool IsInLandAccessList(UUID avatar) public bool IsInLandAccessList(UUID avatar)