From 0091c37ed3fd3f9ed4edf079a61f986daadca16b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 27 Jan 2017 20:21:24 +0000 Subject: [PATCH] several changes relative to objects return and parcel prim counts: avoid null refs, report correct count of returned objects, make obkects counts by ownership coerent with return rules, etc --- OpenSim/Framework/IClientAPI.cs | 2 +- .../World/Land/LandManagementModule.cs | 15 ++++---- .../CoreModules/World/Land/LandObject.cs | 8 +++-- .../CoreModules/World/Land/PrimCountModule.cs | 35 +++++-------------- .../World/Permissions/PermissionsModule.cs | 32 +++++++++-------- .../World/Vegetation/VegetationModule.cs | 3 +- .../Framework/Scenes/Scene.Inventory.cs | 21 ++++++----- .../Framework/Scenes/Scene.PacketHandlers.cs | 5 ++- .../Framework/Scenes/Scene.Permissions.cs | 13 +++++-- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +-- .../Framework/Scenes/SceneObjectGroup.cs | 4 +-- .../TreePopulator/TreePopulatorModule.cs | 2 +- 12 files changed, 75 insertions(+), 69 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index eedba9d2fa..ab6d58fb05 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -107,7 +107,7 @@ namespace OpenSim.Framework public delegate void GenericCall4(Packet packet, IClientAPI remoteClient); public delegate void DeRezObject( - IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID); + IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID, bool AddToReturns = true); public delegate void GenericCall5(IClientAPI remoteClient, bool status); diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 66be5e5082..dfa709592d 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -149,9 +149,11 @@ namespace OpenSim.Region.CoreModules.World.Land parcelInfoCache.Size = 30; // the number of different parcel requests in this region to cache parcelInfoCache.DefaultTTL = new TimeSpan(0, 5, 0); + m_scene.EventManager.OnObjectAddedToScene += EventManagerOnParcelPrimCountAdd; m_scene.EventManager.OnParcelPrimCountAdd += EventManagerOnParcelPrimCountAdd; - m_scene.EventManager.OnParcelPrimCountUpdate += EventManagerOnParcelPrimCountUpdate; + m_scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene; + m_scene.EventManager.OnParcelPrimCountUpdate += EventManagerOnParcelPrimCountUpdate; m_scene.EventManager.OnRequestParcelPrimCountUpdate += EventManagerOnRequestParcelPrimCountUpdate; m_scene.EventManager.OnAvatarEnteringNewParcel += EventManagerOnAvatarEnteringNewParcel; @@ -815,6 +817,9 @@ namespace OpenSim.Region.CoreModules.World.Land throw new Exception("Error: Parcel not found at point " + x + ", " + y); } + if(m_landList.Count == 0 || m_landIDList == null) + return null; + lock (m_landIDList) { try @@ -826,8 +831,6 @@ namespace OpenSim.Region.CoreModules.World.Land return null; } } - - return m_landList[m_landIDList[x / 4, y / 4]]; } // Create a 'parcel is here' bitmap for the parcel identified by the passed landID @@ -1642,9 +1645,9 @@ namespace OpenSim.Region.CoreModules.World.Land foreach (HashSet objs in returns.Values) { List objs2 = new List(objs); - if (m_scene.Permissions.CanReturnObjects(null, remoteClient.AgentId, objs2)) + if (m_scene.Permissions.CanReturnObjects(null, remoteClient, objs2)) { - m_scene.returnObjects(objs2.ToArray(), remoteClient.AgentId); + m_scene.returnObjects(objs2.ToArray(), remoteClient); } else { @@ -2037,7 +2040,7 @@ namespace OpenSim.Region.CoreModules.World.Land { SceneObjectGroup[] objs = new SceneObjectGroup[1]; objs[0] = obj; - ((Scene)client.Scene).returnObjects(objs, client.AgentId); + ((Scene)client.Scene).returnObjects(objs, client); } Dictionary Timers = new Dictionary(); diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 8c0edc83ac..9d84e664dd 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -1664,7 +1664,7 @@ namespace OpenSim.Region.CoreModules.World.Land { SceneObjectGroup[] objs = new SceneObjectGroup[1]; objs[0] = obj; - m_scene.returnObjects(objs, obj.OwnerID); + m_scene.returnObjects(objs, null); } public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) @@ -1695,6 +1695,8 @@ namespace OpenSim.Region.CoreModules.World.Land { if (obj.GroupID == LandData.GroupID) { + if (obj.OwnerID == LandData.OwnerID) + continue; if (!returns.ContainsKey(obj.OwnerID)) returns[obj.OwnerID] = new List(); @@ -1736,8 +1738,8 @@ namespace OpenSim.Region.CoreModules.World.Land foreach (List ol in returns.Values) { - if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) - m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); + if (m_scene.Permissions.CanReturnObjects(this, remote_client, ol)) + m_scene.returnObjects(ol.ToArray(), remote_client); } } diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs index 857f919a06..2a720db660 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs @@ -92,10 +92,8 @@ namespace OpenSim.Region.CoreModules.World.Land m_Scene.RegisterModuleInterface(this); m_Scene.EventManager.OnObjectAddedToScene += OnParcelPrimCountAdd; - m_Scene.EventManager.OnObjectBeingRemovedFromScene += - OnObjectBeingRemovedFromScene; - m_Scene.EventManager.OnParcelPrimCountTainted += - OnParcelPrimCountTainted; + m_Scene.EventManager.OnObjectBeingRemovedFromScene += OnObjectBeingRemovedFromScene; + m_Scene.EventManager.OnParcelPrimCountTainted += OnParcelPrimCountTainted; m_Scene.EventManager.OnLandObjectAdded += delegate(ILandObject lo) { OnParcelPrimCountTainted(); }; } @@ -215,29 +213,15 @@ namespace OpenSim.Region.CoreModules.World.Land else parcelCounts.Users[obj.OwnerID] = partCount; - if (obj.IsSelected) - { + if (obj.IsSelected || obj.GetSittingAvatarsCount() > 0) parcelCounts.Selected += partCount; - } + + if (obj.OwnerID == landData.OwnerID) + parcelCounts.Owner += partCount; + else if (landData.GroupID != UUID.Zero && obj.GroupID == landData.GroupID) + parcelCounts.Group += partCount; else - { - if (landData.IsGroupOwned) - { - if (obj.OwnerID == landData.GroupID) - parcelCounts.Owner += partCount; - else if (landData.GroupID != UUID.Zero && obj.GroupID == landData.GroupID) - parcelCounts.Group += partCount; - else - parcelCounts.Others += partCount; - } - else - { - if (obj.OwnerID == landData.OwnerID) - parcelCounts.Owner += partCount; - else - parcelCounts.Others += partCount; - } - } + parcelCounts.Others += partCount; } } @@ -393,7 +377,6 @@ namespace OpenSim.Region.CoreModules.World.Land count = counts.Owner; count += counts.Group; count += counts.Others; - count += counts.Selected; } } diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index c00112b7ed..279b966b73 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -282,9 +282,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions scenePermissions.OnTerraformLand += CanTerraformLand; scenePermissions.OnBuyLand += CanBuyLand; + scenePermissions.OnReturnObjects += CanReturnObjects; + scenePermissions.OnRezObject += CanRezObject; scenePermissions.OnObjectEntry += CanObjectEntry; - scenePermissions.OnReturnObjects += CanReturnObjects; scenePermissions.OnDuplicateObject += CanDuplicateObject; scenePermissions.OnDeleteObjectByIDs += CanDeleteObjectByIDs; @@ -1621,19 +1622,20 @@ namespace OpenSim.Region.CoreModules.World.Permissions return false; } - private bool CanReturnObjects(ILandObject land, UUID user, List objects) + private bool CanReturnObjects(ILandObject land, ScenePresence sp, List objects) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - ScenePresence sp = m_scene.GetScenePresence(user); - if (sp == null) - return false; + if(sp == null) + return true; // assuming that in this case rights are as owner - bool isPrivUser = sp.IsGod || IsEstateManager(user); + UUID userID = sp.UUID; + bool isPrivUser = sp.IsGod || IsEstateManager(userID); IClientAPI client = sp.ControllingClient; - GroupPowers powers; + + ulong powers = 0; ILandObject l; foreach (SceneObjectGroup g in new List(objects)) @@ -1644,7 +1646,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions continue; } - if (isPrivUser || g.OwnerID == user) + if (isPrivUser || g.OwnerID == userID) continue; // This is a short cut for efficiency. If land is non-null, @@ -1671,7 +1673,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions LandData ldata = l.LandData; // If we own the land outright, then allow // - if (ldata.OwnerID == user) + if (ldata.OwnerID == userID) continue; // Group voodoo @@ -1679,19 +1681,19 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (ldata.IsGroupOwned) { UUID lGroupID = ldata.GroupID; - powers = (GroupPowers)client.GetGroupPowers(lGroupID); // Not a group member, or no rights at all // - if (powers == (GroupPowers)0) + powers = client.GetGroupPowers(lGroupID); + if(powers == 0) { objects.Remove(g); continue; } - + // Group deeded object? // if (g.OwnerID == lGroupID && - (powers & GroupPowers.ReturnGroupOwned) == (GroupPowers)0) + (powers & (ulong)GroupPowers.ReturnGroupOwned) == 0) { objects.Remove(g); continue; @@ -1700,13 +1702,13 @@ namespace OpenSim.Region.CoreModules.World.Permissions // Group set object? // if (g.GroupID == lGroupID && - (powers & GroupPowers.ReturnGroupSet) == (GroupPowers)0) + (powers & (ulong)GroupPowers.ReturnGroupSet) == 0) { objects.Remove(g); continue; } - if ((powers & GroupPowers.ReturnNonGroup) == (GroupPowers)0) + if ((powers & (ulong)GroupPowers.ReturnNonGroup) == 0) { objects.Remove(g); continue; diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs index 04b6f00a39..167f6b50d2 100644 --- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs +++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs @@ -105,8 +105,9 @@ namespace OpenSim.Region.CoreModules.World.Vegetation if (rootPart.Shape.PCode != (byte)PCode.Grass) AdaptTree(ref shape); - m_scene.AddNewSceneObject(sceneObject, true); sceneObject.SetGroup(groupID, null); + m_scene.AddNewSceneObject(sceneObject, true); + sceneObject.AggregatePerms(); return sceneObject; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index dbc7defe6f..2f016fa276 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2085,7 +2085,7 @@ namespace OpenSim.Region.Framework.Scenes /// DeRezAction /// User folder ID to place derezzed object public virtual void DeRezObjects( - IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID) + IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID, bool AddToReturns = true) { // First, see of we can perform the requested action and // build a list of eligible objects @@ -2094,7 +2094,11 @@ namespace OpenSim.Region.Framework.Scenes List takeGroups = new List(); List takeDeleteGroups = new List(); - ScenePresence sp = remoteClient.SceneAgent as ScenePresence; + ScenePresence sp = null; + if(remoteClient != null) + sp = remoteClient.SceneAgent as ScenePresence; + else if(action != DeRezAction.Return) + return; // only Return can be called without a client // Start with true for both, then remove the flags if objects // that we can't derez are part of the selection @@ -2201,13 +2205,14 @@ namespace OpenSim.Region.Framework.Scenes { if (Permissions.CanReturnObjects( null, - remoteClient.AgentId, + remoteClient, new List() {grp})) { permissionToTake = true; permissionToDelete = true; - - AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return"); + if(AddToReturns) + AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, + "parcel owner return"); } } else // Auto return passes through here with null agent @@ -2641,7 +2646,7 @@ namespace OpenSim.Region.Framework.Scenes } public virtual bool returnObjects(SceneObjectGroup[] returnobjects, - UUID AgentId) + IClientAPI client) { List localIDs = new List(); @@ -2651,8 +2656,8 @@ namespace OpenSim.Region.Framework.Scenes "parcel owner return"); localIDs.Add(grp.RootPart.LocalId); } - DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, - UUID.Zero); + DeRezObjects(client, localIDs, UUID.Zero, DeRezAction.Return, + UUID.Zero, false); return true; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 940f80ce11..4fef9c3012 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -185,8 +185,10 @@ namespace OpenSim.Region.Framework.Scenes // A prim is only tainted if it's allowed to be edited by the person clicking it. if (Permissions.CanChangeSelectedState(part, (ScenePresence)remoteClient.SceneAgent)) { + bool oldsel = part.IsSelected; part.IsSelected = true; - EventManager.TriggerParcelPrimCountTainted(); + if(!oldsel) + EventManager.TriggerParcelPrimCountTainted(); } part.SendPropertiesToClient(remoteClient); @@ -228,6 +230,7 @@ namespace OpenSim.Region.Framework.Scenes if (so.OwnerID == remoteClient.AgentId) { so.SetGroup(groupID, remoteClient); + EventManager.TriggerParcelPrimCountTainted(); } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index 45d710aa45..6d3b82f55a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -54,7 +54,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool EditObjectInventoryHandler(UUID objectID, UUID editorID); public delegate bool MoveObjectHandler(SceneObjectGroup sog, ScenePresence sp); public delegate bool ObjectEntryHandler(SceneObjectGroup sog, bool enteringRegion, Vector3 newPoint); - public delegate bool ReturnObjectsHandler(ILandObject land, UUID user, List objects); + public delegate bool ReturnObjectsHandler(ILandObject land, ScenePresence sp, List objects); public delegate bool InstantMessageHandler(UUID user, UUID target); public delegate bool InventoryTransferHandler(UUID user, UUID target); public delegate bool ViewScriptHandler(UUID script, UUID objectID, UUID user); @@ -556,17 +556,24 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region RETURN OBJECT - public bool CanReturnObjects(ILandObject land, UUID user, List objects) + public bool CanReturnObjects(ILandObject land, IClientAPI client, List objects) { bool result = true; ReturnObjectsHandler handler = OnReturnObjects; if (handler != null) { + if(objects == null) + return false; + + ScenePresence sp = null; + if(client != null && client.SceneAgent != null) + sp = client.SceneAgent as ScenePresence; + Delegate[] list = handler.GetInvocationList(); foreach (ReturnObjectsHandler h in list) { - if (h(land, user, objects) == false) + if (h(land, sp, objects) == false) { result = false; break; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4fca4edbb6..5f99b73928 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2604,8 +2604,8 @@ namespace OpenSim.Region.Framework.Scenes { // Otherwise, use this default creation code; sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); - AddNewSceneObject(sceneObject, true); sceneObject.SetGroup(groupID, null); + AddNewSceneObject(sceneObject, true); if (AgentPreferencesService != null) // This will override the brave new full perm world! { @@ -2784,7 +2784,7 @@ namespace OpenSim.Region.Framework.Scenes } if (toReturn.Count > 0) { - returnObjects(toReturn.ToArray(), UUID.Zero); + returnObjects(toReturn.ToArray(), null); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index dff242e213..45196bb8f7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -645,7 +645,7 @@ namespace OpenSim.Region.Framework.Scenes localIDs.Add(sog.RootPart.LocalId); sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition, "Returned at region cross"); - sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero); + sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero, false); } catch (Exception) { @@ -2254,7 +2254,7 @@ namespace OpenSim.Region.Framework.Scenes RootPart.UUID); m_scene.AddReturn(OwnerID == GroupID ? LastOwnerID : OwnerID, Name, AbsolutePosition, "parcel autoreturn"); m_scene.DeRezObjects(null, new List() { RootPart.LocalId }, UUID.Zero, - DeRezAction.Return, UUID.Zero); + DeRezAction.Return, UUID.Zero, false); return; } diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index bf74849b1c..b26fa3298d 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs @@ -523,8 +523,8 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator rootPart.AddFlag(PrimFlags.Phantom); - m_scene.AddNewSceneObject(sceneObject, true); sceneObject.SetGroup(groupID, null); + m_scene.AddNewSceneObject(sceneObject, true); sceneObject.AggregatePerms(); return sceneObject; }