diff options
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.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Land/LandObject.cs | 106 |
1 files changed, 49 insertions, 57 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 9808ebf..c532d0d 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -56,11 +56,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
56 | protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); | 56 | protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); |
57 | protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); | 57 | protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); |
58 | 58 | ||
59 | protected IGroupsModule m_groupsModule; | 59 | protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>(); |
60 | protected const uint PARCEL_FLAG_USE_ACCESS_GROUP = 0x100; // parcel limits access to a group | 60 | protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds |
61 | protected Dictionary<UUID, long> m_isGroupMemberCache = new Dictionary<UUID, long>(); | ||
62 | protected Dictionary<UUID, long> m_notGroupMemberCache = new Dictionary<UUID, long>(); | ||
63 | protected const long m_groupMemberCacheTimeout = 30; // cache invalidation after 30 seconds | ||
64 | 61 | ||
65 | public bool[,] LandBitmap | 62 | public bool[,] LandBitmap |
66 | { | 63 | { |
@@ -138,8 +135,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
138 | else | 135 | else |
139 | LandData.GroupID = UUID.Zero; | 136 | LandData.GroupID = UUID.Zero; |
140 | LandData.IsGroupOwned = is_group_owned; | 137 | LandData.IsGroupOwned = is_group_owned; |
141 | |||
142 | m_groupsModule = scene.RequestModuleInterface<IGroupsModule>(); | ||
143 | } | 138 | } |
144 | 139 | ||
145 | #endregion | 140 | #endregion |
@@ -425,6 +420,48 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
425 | return false; | 420 | return false; |
426 | } | 421 | } |
427 | 422 | ||
423 | public bool HasGroupAccess(UUID avatar) | ||
424 | { | ||
425 | if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) | ||
426 | { | ||
427 | ScenePresence sp; | ||
428 | if (!m_scene.TryGetScenePresence(avatar, out sp)) | ||
429 | { | ||
430 | bool isMember; | ||
431 | if (m_groupMemberCache.TryGetValue(avatar, out isMember)) | ||
432 | return isMember; | ||
433 | |||
434 | IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); | ||
435 | if (groupsModule == null) | ||
436 | return false; | ||
437 | |||
438 | GroupMembershipData[] membership = groupsModule.GetMembershipData(avatar); | ||
439 | if (membership == null || membership.Length == 0) | ||
440 | { | ||
441 | m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); | ||
442 | return false; | ||
443 | } | ||
444 | |||
445 | foreach (GroupMembershipData d in membership) | ||
446 | { | ||
447 | if (d.GroupID == LandData.GroupID) | ||
448 | { | ||
449 | m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); | ||
450 | return true; | ||
451 | } | ||
452 | } | ||
453 | m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); | ||
454 | return false; | ||
455 | } | ||
456 | |||
457 | if (!sp.ControllingClient.IsGroupMember(LandData.GroupID)) | ||
458 | return false; | ||
459 | |||
460 | return true; | ||
461 | } | ||
462 | return false; | ||
463 | } | ||
464 | |||
428 | public bool IsBannedFromLand(UUID avatar) | 465 | public bool IsBannedFromLand(UUID avatar) |
429 | { | 466 | { |
430 | ExpireAccessList(); | 467 | ExpireAccessList(); |
@@ -456,6 +493,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
456 | 493 | ||
457 | public bool IsRestrictedFromLand(UUID avatar) | 494 | public bool IsRestrictedFromLand(UUID avatar) |
458 | { | 495 | { |
496 | if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0) | ||
497 | return false; | ||
498 | |||
459 | if (m_scene.Permissions.IsAdministrator(avatar)) | 499 | if (m_scene.Permissions.IsAdministrator(avatar)) |
460 | return false; | 500 | return false; |
461 | 501 | ||
@@ -465,58 +505,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
465 | if (avatar == LandData.OwnerID) | 505 | if (avatar == LandData.OwnerID) |
466 | return false; | 506 | return false; |
467 | 507 | ||
468 | if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0) | 508 | if (HasGroupAccess(avatar)) |
469 | return false; | ||
470 | |||
471 | if (IsInLandAccessList(avatar)) | ||
472 | return false; | 509 | return false; |
473 | 510 | ||
474 | UUID groupID = LandData.GroupID; | 511 | return !IsInLandAccessList(avatar); |
475 | |||
476 | if ((m_groupsModule != null) && (groupID != UUID.Zero) && ((LandData.Flags & PARCEL_FLAG_USE_ACCESS_GROUP) == PARCEL_FLAG_USE_ACCESS_GROUP)) | ||
477 | { | ||
478 | long now = Util.UnixTimeSinceEpoch(); | ||
479 | |||
480 | if (m_isGroupMemberCache.ContainsKey(avatar)) | ||
481 | { | ||
482 | if (now - m_isGroupMemberCache[avatar] <= m_groupMemberCacheTimeout) // invalid? | ||
483 | { | ||
484 | m_isGroupMemberCache[avatar] = now; | ||
485 | return false; | ||
486 | } | ||
487 | else | ||
488 | m_isGroupMemberCache.Remove(avatar); | ||
489 | } | ||
490 | |||
491 | if (m_notGroupMemberCache.ContainsKey(avatar)) | ||
492 | { | ||
493 | if (now - m_notGroupMemberCache[avatar] <= m_groupMemberCacheTimeout) // invalid? | ||
494 | { | ||
495 | // m_notGroupMemberCache[avatar] = now; | ||
496 | return true; | ||
497 | } | ||
498 | else | ||
499 | m_notGroupMemberCache.Remove(avatar); | ||
500 | } | ||
501 | |||
502 | GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(avatar); | ||
503 | |||
504 | if (GroupMembership != null) | ||
505 | { | ||
506 | for (int i = 0; i < GroupMembership.Length; i++) | ||
507 | { | ||
508 | if (groupID == GroupMembership[i].GroupID) | ||
509 | { | ||
510 | m_isGroupMemberCache[avatar] = now; | ||
511 | return false; | ||
512 | } | ||
513 | } | ||
514 | } | ||
515 | |||
516 | m_notGroupMemberCache[avatar] = now; | ||
517 | } | ||
518 | |||
519 | return true; | ||
520 | } | 512 | } |
521 | 513 | ||
522 | public bool IsInLandAccessList(UUID avatar) | 514 | public bool IsInLandAccessList(UUID avatar) |