From cc8897fcebdc9d3e875c9bf745ecb77678a776e9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 26 Mar 2011 00:34:49 +0000 Subject: [PATCH] Add test for PCM taint. This currently fails due to unexpected behaviour of SceneGraph.ForEachSOG(). This will be corrected soon. Also adds lots of temproarily debug logging --- OpenSim/Framework/ILandObject.cs | 112 ++++++++++++++++++ .../ClientStack/LindenUDP/LLClientView.cs | 2 + .../CoreModules/World/Land/PrimCountModule.cs | 79 +++++++++--- .../World/Land/Tests/PrimCountModuleTests.cs | 24 +++- 4 files changed, 201 insertions(+), 16 deletions(-) create mode 100644 OpenSim/Framework/ILandObject.cs diff --git a/OpenSim/Framework/ILandObject.cs b/OpenSim/Framework/ILandObject.cs new file mode 100644 index 0000000000..931e24aebb --- /dev/null +++ b/OpenSim/Framework/ILandObject.cs @@ -0,0 +1,112 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections.Generic; +using OpenMetaverse; + +namespace OpenSim.Framework +{ + public delegate int overrideParcelMaxPrimCountDelegate(ILandObject obj); + public delegate int overrideSimulatorMaxPrimCountDelegate(ILandObject obj); + + public interface ILandObject + { + int GetParcelMaxPrimCount(ILandObject thisObject); + int GetSimulatorMaxPrimCount(ILandObject thisObject); + int GetPrimsFree(); + + LandData LandData { get; set; } + bool[,] LandBitmap { get; set; } + UUID RegionUUID { get; } + + /// + /// Prim counts for this land object. + /// + IPrimCounts PrimCounts { get; set; } + + /// + /// The start point for the land object. This is the western-most point as one scans land working from + /// north to south. + /// + Vector3 StartPoint { get; } + + /// + /// The end point for the land object. This is the eastern-most point as one scans land working from + /// south to north. + /// + Vector3 EndPoint { get; } + + bool ContainsPoint(int x, int y); + + ILandObject Copy(); + + void SendLandUpdateToAvatarsOverMe(); + + void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client); + void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client); + bool IsEitherBannedOrRestricted(UUID avatar); + bool IsBannedFromLand(UUID avatar); + bool IsRestrictedFromLand(UUID avatar); + void SendLandUpdateToClient(IClientAPI remote_client); + void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client); + List CreateAccessListArrayByFlag(AccessList flag); + void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, IClientAPI remote_client); + void UpdateAccessList(uint flags, UUID transactionID, int sequenceID, int sections, List entries, IClientAPI remote_client); + void UpdateLandBitmapByteArray(); + void SetLandBitmapFromByteArray(); + bool[,] GetLandBitmap(); + void ForceUpdateLandInfo(); + void SetLandBitmap(bool[,] bitmap); + + bool[,] BasicFullRegionLandBitmap(); + bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y); + bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value); + bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add); + void SendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client); + void SendLandObjectOwners(IClientAPI remote_client); + void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client); + void ResetLandPrimCounts(); + void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area); + + void DeedToGroup(UUID groupID); + + void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel); + void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel); + + /// + /// Set the media url for this land parcel + /// + /// + void SetMediaUrl(string url); + + /// + /// Set the music url for this land parcel + /// + /// + void SetMusicUrl(string url); + } +} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 6138056daf..0b6b04dc3b 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4276,6 +4276,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP int sequence_id, bool snap_selection, int request_result, ILandObject lo, float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags) { + m_log.DebugFormat("[LLCLIENTVIEW]: Sending land properties for {0} to {1}", lo.LandData.GlobalID, Name); + LandData landData = lo.LandData; ParcelPropertiesMessage updateMessage = new ParcelPropertiesMessage(); diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs index 9fd347e371..72115a847c 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs @@ -51,8 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Land public class PrimCountModule : IPrimCountModule, INonSharedRegionModule { -// private static readonly ILog m_log = -// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_Scene; private Dictionary m_PrimCounts = @@ -123,6 +122,11 @@ namespace OpenSim.Region.CoreModules.World.Land { if (!m_Tainted) AddObject(obj); + else + m_log.DebugFormat( + "[PRIM COUNT MODULE]: Ignoring OnParcelPrimCountAdd() for {0} on {1} since count is tainted", + obj.Name, m_Scene.RegionInfo.RegionName); + } } @@ -133,11 +137,18 @@ namespace OpenSim.Region.CoreModules.World.Land { if (!m_Tainted) RemoveObject(obj); + else + m_log.DebugFormat( + "[PRIM COUNT MODULE]: Ignoring OnObjectBeingRemovedFromScene() for {0} on {1} since count is tainted", + obj.Name, m_Scene.RegionInfo.RegionName); } } private void OnParcelPrimCountTainted() { + m_log.DebugFormat( + "[PRIM COUNT MODULE]: OnParcelPrimCountTainted() called on {0}", m_Scene.RegionInfo.RegionName); + lock (m_TaintLock) m_Tainted = true; } @@ -163,7 +174,7 @@ namespace OpenSim.Region.CoreModules.World.Land // NOTE: Call under Taint Lock private void AddObject(SceneObjectGroup obj) { -// m_log.DebugFormat("[PRIM COUNT MODULE]: Adding object {0} to prim count", obj.Name); + m_log.DebugFormat("[PRIM COUNT MODULE]: Adding object {0} {1} to prim count", obj.Name, obj.UUID); if (obj.IsAttachment) return; @@ -214,10 +225,14 @@ namespace OpenSim.Region.CoreModules.World.Land // NOTE: Call under Taint Lock private void RemoveObject(SceneObjectGroup obj) { + m_log.DebugFormat("[PRIM COUNT MODULE]: Removing object {0} {1} from prim count", obj.Name, obj.UUID); } public IPrimCounts GetPrimCounts(UUID parcelID) { + m_log.DebugFormat( + "[PRIM COUNT MODULE]: GetPrimCounts for parcel {0} in {1}", parcelID, m_Scene.RegionInfo.RegionName); + PrimCounts primCounts; lock (m_PrimCounts) @@ -239,7 +254,7 @@ namespace OpenSim.Region.CoreModules.World.Land /// public int GetOwnerCount(UUID parcelID) { -// m_log.DebugFormat("[PRIM COUNT MODULE]: GetOwnerCount for {0}", parcelID); + int count = 0; lock (m_TaintLock) { @@ -248,9 +263,14 @@ namespace OpenSim.Region.CoreModules.World.Land ParcelCounts counts; if (m_ParcelCounts.TryGetValue(parcelID, out counts)) - return counts.Owner; + count = counts.Owner; } - return 0; + + m_log.DebugFormat( + "[PRIM COUNT MODULE]: GetOwnerCount for parcel {0} in {1} returning {2}", + parcelID, m_Scene.RegionInfo.RegionName, count); + + return count; } /// @@ -260,6 +280,8 @@ namespace OpenSim.Region.CoreModules.World.Land /// public int GetGroupCount(UUID parcelID) { + int count = 0; + lock (m_TaintLock) { if (m_Tainted) @@ -267,9 +289,14 @@ namespace OpenSim.Region.CoreModules.World.Land ParcelCounts counts; if (m_ParcelCounts.TryGetValue(parcelID, out counts)) - return counts.Group; + count = counts.Group; } - return 0; + + m_log.DebugFormat( + "[PRIM COUNT MODULE]: GetGroupCount for parcel {0} in {1} returning {2}", + parcelID, m_Scene.RegionInfo.RegionName, count); + + return count; } /// @@ -279,6 +306,8 @@ namespace OpenSim.Region.CoreModules.World.Land /// public int GetOthersCount(UUID parcelID) { + int count = 0; + lock (m_TaintLock) { if (m_Tainted) @@ -286,9 +315,14 @@ namespace OpenSim.Region.CoreModules.World.Land ParcelCounts counts; if (m_ParcelCounts.TryGetValue(parcelID, out counts)) - return counts.Others; + count = counts.Others; } - return 0; + + m_log.DebugFormat( + "[PRIM COUNT MODULE]: GetOthersCount for parcel {0} in {1} returning {2}", + parcelID, m_Scene.RegionInfo.RegionName, count); + + return count; } /// @@ -298,6 +332,8 @@ namespace OpenSim.Region.CoreModules.World.Land /// public int GetSimulatorCount(UUID parcelID) { + int count = 0; + lock (m_TaintLock) { if (m_Tainted) @@ -308,10 +344,15 @@ namespace OpenSim.Region.CoreModules.World.Land { int val; if (m_SimwideCounts.TryGetValue(owner, out val)) - return val; + count = val; } } - return 0; + + m_log.DebugFormat( + "[PRIM COUNT MODULE]: GetOthersCount for parcel {0} in {1} returning {2}", + parcelID, m_Scene.RegionInfo.RegionName, count); + + return count; } /// @@ -322,6 +363,8 @@ namespace OpenSim.Region.CoreModules.World.Land /// public int GetUserCount(UUID parcelID, UUID userID) { + int count = 0; + lock (m_TaintLock) { if (m_Tainted) @@ -332,16 +375,21 @@ namespace OpenSim.Region.CoreModules.World.Land { int val; if (counts.Users.TryGetValue(userID, out val)) - return val; + count = val; } } - return 0; + + m_log.DebugFormat( + "[PRIM COUNT MODULE]: GetUserCount for user {0} in parcel {1} in region {2} returning {3}", + userID, parcelID, m_Scene.RegionInfo.RegionName, count); + + return count; } // NOTE: This method MUST be called while holding the taint lock! private void Recount() { -// m_log.DebugFormat("[PRIM COUNT MODULE]: Recounting prims on {0}", m_Scene.RegionInfo.RegionName); + m_log.DebugFormat("[PRIM COUNT MODULE]: Recounting prims on {0}", m_Scene.RegionInfo.RegionName); m_OwnerMap.Clear(); m_SimwideCounts.Clear(); @@ -367,6 +415,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (!m_OwnerMap.ContainsKey(k)) m_PrimCounts.Remove(k); } + m_Tainted = false; } } diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index c9d393f4d6..80b28598ab 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs @@ -126,6 +126,28 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests Assert.That(pc.Users[m_userId], Is.EqualTo(1)); Assert.That(pc.Users[m_dummyUserId], Is.EqualTo(0)); Assert.That(pc.Simulator, Is.EqualTo(1)); - } + } + + /// + /// Test the count is correct after is has been tainted. + /// + [Test] + public void TestTaint() + { + TestHelper.InMethod(); + IPrimCounts pc = m_lo.PrimCounts; + + SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, 0x01); + m_scene.AddNewSceneObject(sog, false); + + m_pcm.TaintPrimCount(); + + Assert.That(pc.Owner, Is.EqualTo(3)); + Assert.That(pc.Group, Is.EqualTo(0)); + Assert.That(pc.Others, Is.EqualTo(0)); + Assert.That(pc.Users[m_userId], Is.EqualTo(3)); + Assert.That(pc.Users[m_dummyUserId], Is.EqualTo(0)); + Assert.That(pc.Simulator, Is.EqualTo(3)); + } } } \ No newline at end of file