diff --git a/OpenSim/Framework/ILandObject.cs b/OpenSim/Framework/ILandObject.cs index 7a24d1ec6a..8465c86e11 100644 --- a/OpenSim/Framework/ILandObject.cs +++ b/OpenSim/Framework/ILandObject.cs @@ -38,6 +38,7 @@ namespace OpenSim.Framework int GetParcelMaxPrimCount(); int GetSimulatorMaxPrimCount(); int GetPrimsFree(); + Dictionary GetLandObjectOwners(); LandData LandData { get; set; } bool[,] LandBitmap { get; set; } diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 2390118284..44d05b74b0 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -127,6 +127,7 @@ namespace OpenSim.Framework private int m_physPrimMax = 0; private bool m_clampPrimSize = false; private int m_objectCapacity = 0; + private int m_maxPrimsPerUser = -1; private int m_linksetCapacity = 0; private int m_agentCapacity = 0; private string m_regionType = String.Empty; @@ -325,6 +326,11 @@ namespace OpenSim.Framework get { return m_objectCapacity; } } + public int MaxPrimsPerUser + { + get { return m_maxPrimsPerUser; } + } + public int LinksetCapacity { get { return m_linksetCapacity; } @@ -709,6 +715,9 @@ namespace OpenSim.Framework m_objectCapacity = config.GetInt("MaxPrims", 15000); allKeys.Remove("MaxPrims"); + m_maxPrimsPerUser = config.GetInt("MaxPrimsPerUser", -1); + allKeys.Remove("MaxPrimsPerUser"); + m_linksetCapacity = config.GetInt("LinksetPrims", 0); allKeys.Remove("LinksetPrims"); @@ -834,6 +843,9 @@ namespace OpenSim.Framework if (m_objectCapacity > 0) config.Set("MaxPrims", m_objectCapacity); + if (m_maxPrimsPerUser > -1) + config.Set("MaxPrimsPerUser", m_maxPrimsPerUser); + if (m_linksetCapacity > 0) config.Set("LinksetPrims", m_linksetCapacity); @@ -946,6 +958,9 @@ namespace OpenSim.Framework configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "Max objects this sim will hold", m_objectCapacity.ToString(), true); + configMember.addConfigurationOption("prims_per_user", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Max objects one user may rez", m_maxPrimsPerUser.ToString(), true); + configMember.addConfigurationOption("linkset_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "Max prims an object will hold", m_linksetCapacity.ToString(), true); @@ -1096,6 +1111,9 @@ namespace OpenSim.Framework case "object_capacity": m_objectCapacity = (int)configuration_result; break; + case "prims_per_user": + m_maxPrimsPerUser = (int)configuration_result; + break; case "linkset_capacity": m_linksetCapacity = (int)configuration_result; break; diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs index b977ad84ec..2b421e596b 100644 --- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs +++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs @@ -102,20 +102,34 @@ namespace OpenSim.Region.OptionalModules public void RegionLoaded(Scene scene) { m_dialogModule = scene.RequestModuleInterface(); - } + } - private bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition, Scene scene) + private bool CanRezObject(int objectCount, UUID ownerID, Vector3 objectPosition, Scene scene) { ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); - int usedPrims = lo.PrimCounts.Total; - int simulatorCapacity = lo.GetSimulatorMaxPrimCount(); - if (objectCount + usedPrims > simulatorCapacity) + string response = DoCommonChecks(objectCount, ownerID, lo, scene); + + if (response != null) { - m_dialogModule.SendAlertToUser(owner, "Unable to rez object because the parcel is too full"); + m_dialogModule.SendAlertToUser(ownerID, response); return false; } + return true; + } + //OnDuplicateObject + private bool CanDuplicateObject(int objectCount, UUID objectID, UUID ownerID, Scene scene, Vector3 objectPosition) + { + ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); + + string response = DoCommonChecks(objectCount, ownerID, lo, scene); + + if (response != null) + { + m_dialogModule.SendAlertToUser(ownerID, response); + return false; + } return true; } @@ -127,12 +141,12 @@ namespace OpenSim.Region.OptionalModules ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); - // newParcel will be null only if it outside of our current region. If this is the case, then the + // newParcel will be null only if it outside of our current region. If this is the case, then the // receiving permissions will perform the check. if (newParcel == null) return true; - - // The prim hasn't crossed a region boundry so we don't need to worry + + // The prim hasn't crossed a region boundary so we don't need to worry // about prim counts here if(oldParcel.Equals(newParcel)) { @@ -148,32 +162,63 @@ namespace OpenSim.Region.OptionalModules // TODO: Add Special Case here for temporary prims - int usedPrims = newParcel.PrimCounts.Total; - int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount(); - - if (objectCount + usedPrims > simulatorCapacity) + string response = DoCommonChecks(objectCount, obj.OwnerID, newParcel, scene); + + if (response != null) { - m_dialogModule.SendAlertToUser(obj.OwnerID, "Unable to move object because the destination parcel is too full"); + m_dialogModule.SendAlertToUser(obj.OwnerID, response); return false; } - return true; } - //OnDuplicateObject - private bool CanDuplicateObject(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition) + private string DoCommonChecks(int objectCount, UUID ownerID, ILandObject lo, Scene scene) { - ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); + string response = null; + EstateSettings estateSettings = scene.RegionInfo.EstateSettings; + + // counts don't seem to be updated, so force it. + scene.EventManager.TriggerParcelPrimCountUpdate(); + int usedPrims = lo.PrimCounts.Total; int simulatorCapacity = lo.GetSimulatorMaxPrimCount(); - if(objectCount + usedPrims > simulatorCapacity) + if ((objectCount + usedPrims) > simulatorCapacity) { - m_dialogModule.SendAlertToUser(owner, "Unable to duplicate object because the parcel is too full"); - return false; + response = "Unable to rez object because the parcel is too full"; } - - return true; + else + { + int maxPrimsPerUser = scene.RegionInfo.MaxPrimsPerUser; + if (maxPrimsPerUser >= 0) + { + // per-user prim limit is set + if (ownerID != lo.LandData.OwnerID || lo.LandData.IsGroupOwned) + { + // caller is not the sole parcel owner + if (ownerID != estateSettings.EstateOwner) + { + // caller is NOT the Estate owner + List mgrs = new List(estateSettings.EstateManagers); + if (!mgrs.Contains(ownerID)) + { + // caller is NOT an Estate Manager, so check quota + Dictionary objectMap = lo.GetLandObjectOwners(); + int currentCount; + if (!objectMap.TryGetValue(ownerID, out currentCount)) + { + currentCount = 0; + } + if ((currentCount + objectCount) > maxPrimsPerUser) + { + response = "Unable to rez object because you have reached your limit"; + } + } + } + } + } + } + return response; } } -} \ No newline at end of file +}