From 423d03eaefcae1bcaff8e4d16da014d350c91c42 Mon Sep 17 00:00:00 2001 From: mingchen Date: Sat, 14 Jul 2007 15:11:36 +0000 Subject: [PATCH] *Added support for prim counting on parcels **No restrictions yet in place, or total prim count --- OpenSim/Framework/General/Types/ParcelData.cs | 4 + OpenSim/Region/Environment/ParcelManager.cs | 117 ++++++++++++++++-- .../Region/Environment/Scenes/Primitive.cs | 26 +++- OpenSim/Region/Environment/Scenes/Scene.cs | 23 +++- .../Region/Environment/Scenes/SceneEvents.cs | 11 ++ .../Region/Environment/Scenes/SceneObject.cs | 76 +++++++++--- 6 files changed, 229 insertions(+), 28 deletions(-) diff --git a/OpenSim/Framework/General/Types/ParcelData.cs b/OpenSim/Framework/General/Types/ParcelData.cs index ac34a26100..2d332f5f9a 100644 --- a/OpenSim/Framework/General/Types/ParcelData.cs +++ b/OpenSim/Framework/General/Types/ParcelData.cs @@ -47,6 +47,8 @@ namespace OpenSim.Framework.Types public int claimPrice = 0; //Unemplemented public LLUUID groupID = new LLUUID(); //Unemplemented public int groupPrims = 0; //Unemplemented + public int otherPrims = 0; //Unemplemented + public int ownerPrims = 0; //Unemplemented public int salePrice = 0; //Unemeplemented. Parcels price. public Parcel.ParcelStatus parcelStatus = Parcel.ParcelStatus.Leased; public uint parcelFlags = (uint)Parcel.ParcelFlags.AllowFly | (uint)Parcel.ParcelFlags.AllowLandmark | (uint)Parcel.ParcelFlags.AllowAllObjectEntry | (uint)Parcel.ParcelFlags.AllowDeedToGroup | (uint)Parcel.ParcelFlags.AllowTerraform | (uint)Parcel.ParcelFlags.CreateObjects | (uint)Parcel.ParcelFlags.AllowOtherScripts; @@ -84,6 +86,8 @@ namespace OpenSim.Framework.Types parcelData.globalID = this.globalID; parcelData.groupID = this.groupID; parcelData.groupPrims = this.groupPrims; + parcelData.otherPrims = this.otherPrims; + parcelData.ownerPrims = this.ownerPrims; parcelData.isGroupOwned = this.isGroupOwned; parcelData.localID = this.localID; parcelData.landingType = this.landingType; diff --git a/OpenSim/Region/Environment/ParcelManager.cs b/OpenSim/Region/Environment/ParcelManager.cs index b9c4067434..981898fb4d 100644 --- a/OpenSim/Region/Environment/ParcelManager.cs +++ b/OpenSim/Region/Environment/ParcelManager.cs @@ -75,6 +75,11 @@ namespace OpenSim.Region.Environment private int lastParcelLocalID = START_PARCEL_LOCAL_ID - 1; private int[,] parcelIDList = new int[64, 64]; + /// + /// Set to true when a prim is moved, created, added. Performs a prim count update + /// + public bool parcelPrimCountTainted = false; + private Scene m_world; private RegionInfo m_regInfo; @@ -190,6 +195,13 @@ namespace OpenSim.Region.Environment /// Value between 0 - 256 on the x axis of the point /// Value between 0 - 256 on the y axis of the point /// Parcel at the point supplied + public Parcel getParcel(float x_float, float y_float) + { + int x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float))); + int y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float))); + + return getParcel(x, y); + } public Parcel getParcel(int x, int y) { if (x > 256 || y > 256 || x < 0 || y < 0) @@ -200,7 +212,6 @@ namespace OpenSim.Region.Environment { return parcelList[parcelIDList[x / 4, y / 4]]; } - } #endregion @@ -262,9 +273,11 @@ namespace OpenSim.Region.Environment parcelList[startParcelIndex].setParcelBitmap(Parcel.modifyParcelBitmapSquare(startParcel.getParcelBitmap(), start_x, start_y, end_x, end_y, false)); parcelList[startParcelIndex].forceUpdateParcelInfo(); + + this.setPrimsTainted(); + //Now add the new parcel Parcel result = addParcel(newParcel); - result.sendParcelUpdateToAvatarsOverMe(); @@ -326,6 +339,8 @@ namespace OpenSim.Region.Environment } + this.setPrimsTainted(); + masterParcel.sendParcelUpdateToAvatarsOverMe(); return true; @@ -493,13 +508,46 @@ namespace OpenSim.Region.Environment Avatar clientAvatar = m_world.RequestAvatar(remote_client.AgentId); if (clientAvatar != null) { - Parcel over = getParcel(Convert.ToInt32(clientAvatar.Pos.X), Convert.ToInt32(clientAvatar.Pos.Y)); + Parcel over = getParcel(clientAvatar.Pos.X,clientAvatar.Pos.Y); if (over != null) { over.sendParcelProperties(0, false, 0, remote_client); } } } + + public void resetAllParcelPrimCounts() + { + foreach (Parcel p in parcelList.Values) + { + p.resetParcelPrimCounts(); + } + } + + public void addPrimToParcelCounts(SceneObject obj) + { + LLVector3 position = obj.rootPrimitive.Pos; + int pos_x = Convert.ToInt32(Math.Round(position.X)); + int pos_y = Convert.ToInt32(Math.Round(position.Y)); + Parcel parcelUnderPrim = getParcel(pos_x, pos_y); + if (parcelUnderPrim != null) + { + parcelUnderPrim.addPrimToCount(obj); + } + } + + public void removePrimFromParcelCounts(SceneObject obj) + { + foreach (Parcel p in parcelList.Values) + { + p.removePrimFromCount(obj); + } + } + + public void setPrimsTainted() + { + this.parcelPrimCountTainted = true; + } #endregion } #endregion @@ -513,6 +561,8 @@ namespace OpenSim.Region.Environment { #region Member Variables public ParcelData parcelData = new ParcelData(); + public List primsOverMe = new List(); + public Scene m_world; private bool[,] parcelBitmap = new bool[64, 64]; @@ -602,9 +652,9 @@ namespace OpenSim.Region.Environment updatePacket.ParcelData.Name = Helpers.StringToField(parcelData.parcelName); updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented updatePacket.ParcelData.OtherCount = 0; //unemplemented - updatePacket.ParcelData.OtherPrims = 0; //unemplented + updatePacket.ParcelData.OtherPrims = parcelData.groupPrims; updatePacket.ParcelData.OwnerID = parcelData.ownerID; - updatePacket.ParcelData.OwnerPrims = 0; //unemplemented + updatePacket.ParcelData.OwnerPrims = parcelData.ownerPrims; updatePacket.ParcelData.ParcelFlags = parcelData.parcelFlags; updatePacket.ParcelData.ParcelPrimBonus = m_world.RegionInfo.estateSettings.objectBonusFactor; updatePacket.ParcelData.PassHours = parcelData.passHours; @@ -616,7 +666,7 @@ namespace OpenSim.Region.Environment updatePacket.ParcelData.RegionPushOverride = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.RestrictPushObject) > 0); updatePacket.ParcelData.RentPrice = 0; updatePacket.ParcelData.RequestResult = request_result; - updatePacket.ParcelData.SalePrice = parcelData.salePrice; //unemplemented + updatePacket.ParcelData.SalePrice = parcelData.salePrice; updatePacket.ParcelData.SelectedPrims = 0; //unemeplemented updatePacket.ParcelData.SelfCount = 0;//unemplemented updatePacket.ParcelData.SequenceID = sequence_id; @@ -625,7 +675,7 @@ namespace OpenSim.Region.Environment updatePacket.ParcelData.SnapSelection = snap_selection; updatePacket.ParcelData.SnapshotID = parcelData.snapshotID; updatePacket.ParcelData.Status = (byte)parcelData.parcelStatus; - updatePacket.ParcelData.TotalPrims = 0; //unemplemented + updatePacket.ParcelData.TotalPrims = parcelData.ownerPrims + parcelData.groupPrims + parcelData.otherPrims; updatePacket.ParcelData.UserLocation = parcelData.userLocation; updatePacket.ParcelData.UserLookAt = parcelData.userLookAt; remote_client.OutPacket((Packet)updatePacket); @@ -900,6 +950,59 @@ namespace OpenSim.Region.Environment } #endregion + public void resetParcelPrimCounts() + { + parcelData.groupPrims = 0; + parcelData.ownerPrims = 0; + parcelData.groupPrims = 0; + primsOverMe.Clear(); + } + + public void addPrimToCount(SceneObject obj) + { + LLUUID prim_owner = obj.rootPrimitive.OwnerID; + int prim_count = obj.primCount; + + if(prim_owner == parcelData.ownerID) + { + parcelData.ownerPrims += prim_count; + } + else if (prim_owner == parcelData.groupID) + { + parcelData.groupPrims += prim_count; + } + else + { + parcelData.otherPrims += prim_count; + } + primsOverMe.Add(obj); + + } + + public void removePrimFromCount(SceneObject obj) + { + if (primsOverMe.Contains(obj)) + { + LLUUID prim_owner = obj.rootPrimitive.OwnerID; + int prim_count = obj.primCount; + + if (prim_owner == parcelData.ownerID) + { + parcelData.ownerPrims -= prim_count; + } + else if (prim_owner == parcelData.groupID) + { + parcelData.groupPrims -= prim_count; + } + else + { + parcelData.otherPrims -= prim_count; + } + + primsOverMe.Remove(obj); + } + } + #endregion diff --git a/OpenSim/Region/Environment/Scenes/Primitive.cs b/OpenSim/Region/Environment/Scenes/Primitive.cs index e20870fb50..79d5785ddd 100644 --- a/OpenSim/Region/Environment/Scenes/Primitive.cs +++ b/OpenSim/Region/Environment/Scenes/Primitive.cs @@ -45,6 +45,8 @@ namespace OpenSim.Region.Environment.Scenes public bool m_isRootPrim; public EntityBase m_Parent; + private ParcelManager m_parcelManager; + #region Properties /// /// If rootprim, will return world position @@ -130,10 +132,12 @@ namespace OpenSim.Region.Environment.Scenes /// /// /// - public Primitive(ulong regionHandle, Scene world, LLUUID ownerID, uint localID, bool isRoot, EntityBase parent, SceneObject rootObject, PrimitiveBaseShape shape, LLVector3 pos) + public Primitive(ulong regionHandle, Scene world, ParcelManager parcelManager, LLUUID ownerID, uint localID, bool isRoot, EntityBase parent, SceneObject rootObject, PrimitiveBaseShape shape, LLVector3 pos) { + m_regionHandle = regionHandle; m_world = world; + m_parcelManager = parcelManager; inventoryItems = new Dictionary(); this.m_Parent = parent; this.m_isRootPrim = isRoot; @@ -141,6 +145,9 @@ namespace OpenSim.Region.Environment.Scenes this.CreateFromShape(ownerID, localID, pos, shape); this.Rotation = Axiom.Math.Quaternion.Identity; + + + m_parcelManager.setPrimsTainted(); } /// @@ -149,11 +156,19 @@ namespace OpenSim.Region.Environment.Scenes /// Empty constructor for duplication public Primitive() { - + m_parcelManager.setPrimsTainted(); } #endregion + #region Destructors + + ~Primitive() + { + m_parcelManager.setPrimsTainted(); + } + #endregion + #region Duplication public Primitive Copy(EntityBase parent, SceneObject rootParent) @@ -260,6 +275,8 @@ namespace OpenSim.Region.Environment.Scenes this.m_world.DeleteEntity(linkObject.rootUUID); linkObject.DeleteAllChildren(); + + m_parcelManager.setPrimsTainted(); } /// @@ -335,6 +352,7 @@ namespace OpenSim.Region.Environment.Scenes prim.m_pos += offset; prim.updateFlag = 2; } + m_parcelManager.setPrimsTainted(); } /// @@ -385,6 +403,8 @@ namespace OpenSim.Region.Environment.Scenes this.Pos = newPos; this.updateFlag = 2; + + m_parcelManager.setPrimsTainted(); } /// @@ -419,6 +439,8 @@ namespace OpenSim.Region.Environment.Scenes this.m_pos = newPos; this.updateFlag = 2; } + + m_parcelManager.setPrimsTainted(); } #endregion diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 01e67529da..81bab9a338 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -59,6 +59,7 @@ namespace OpenSim.Region.Environment.Scenes private uint _primCount = 702000; private System.Threading.Mutex _primAllocateMutex = new Mutex(false); private int storageCount; + private int parcelPrimCheckCount; private Mutex updateLock; protected AuthenticateSessionsBase authenticateHandler; @@ -144,6 +145,8 @@ namespace OpenSim.Region.Environment.Scenes Terrain = new TerrainEngine(); ScenePresence.LoadAnims(); + + this.performParcelPrimCountUpdate(); this.httpListener = httpServer; } #endregion @@ -211,6 +214,18 @@ namespace OpenSim.Region.Environment.Scenes this.Backup(); storageCount = 0; } + + this.parcelPrimCheckCount++; + if (this.parcelPrimCheckCount > 50) //check every 5 seconds for tainted prims + { + if (m_parcelManager.parcelPrimCountTainted) + { + //Perform parcel update of prim count + performParcelPrimCountUpdate(); + this.parcelPrimCheckCount = 0; + } + } + } catch (Exception e) { @@ -441,7 +456,7 @@ namespace OpenSim.Region.Environment.Scenes { try { - SceneObject sceneOb = new SceneObject(m_regionHandle, this, ownerID, this.PrimIDAllocate(), pos, shape); + SceneObject sceneOb = new SceneObject(m_regionHandle, this, this.m_eventManager,this.m_parcelManager, ownerID, this.PrimIDAllocate(), pos, shape); this.Entities.Add(sceneOb.rootUUID, sceneOb); // Trigger event for listeners @@ -809,6 +824,12 @@ namespace OpenSim.Region.Environment.Scenes return this.commsManager.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position); } + public void performParcelPrimCountUpdate() + { + m_parcelManager.resetAllParcelPrimCounts(); + m_eventManager.TriggerParcelPrimCountUpdate(); + m_parcelManager.parcelPrimCountTainted = false; + } #endregion } diff --git a/OpenSim/Region/Environment/Scenes/SceneEvents.cs b/OpenSim/Region/Environment/Scenes/SceneEvents.cs index deecfd5404..685ed8c9ec 100644 --- a/OpenSim/Region/Environment/Scenes/SceneEvents.cs +++ b/OpenSim/Region/Environment/Scenes/SceneEvents.cs @@ -19,6 +19,9 @@ namespace OpenSim.Region.Environment.Scenes public delegate void OnRemovePresenceDelegate(LLUUID uuid); public event OnRemovePresenceDelegate OnRemovePresence; + public delegate void OnParcelPrimCountUpdateDelegate(); + public event OnParcelPrimCountUpdateDelegate OnParcelPrimCountUpdate; + public void TriggerOnFrame() { if (OnFrame != null) @@ -48,5 +51,13 @@ namespace OpenSim.Region.Environment.Scenes OnBackup(dstore); } } + + public void TriggerParcelPrimCountUpdate() + { + if (OnParcelPrimCountUpdate != null) + { + OnParcelPrimCountUpdate(); + } + } } } diff --git a/OpenSim/Region/Environment/Scenes/SceneObject.cs b/OpenSim/Region/Environment/Scenes/SceneObject.cs index d1a3e7059f..f4c408359c 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObject.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObject.cs @@ -47,6 +47,9 @@ namespace OpenSim.Region.Environment.Scenes private PhysicsScene m_PhysScene; private PhysicsActor m_PhysActor; + private EventManager m_eventManager; + private ParcelManager m_parcelManager; + public LLUUID rootUUID { get @@ -65,27 +68,29 @@ namespace OpenSim.Region.Environment.Scenes } } - /// - /// - /// - public SceneObject(ulong regionHandle, Scene world, LLUUID ownerID, uint localID, LLVector3 pos, PrimitiveBaseShape shape) + public int primCount { - m_regionHandle = regionHandle; - m_world = world; - this.Pos = pos; - this.CreateRootFromShape(ownerID, localID, shape, pos); - - // Setup a backup event listener - world.EventManager.OnBackup += new EventManager.OnBackupDelegate(ProcessBackup); + get + { + return this.ChildPrimitives.Count; + } } /// - /// Processes backup + /// /// - /// - void ProcessBackup(OpenSim.Region.Interfaces.IRegionDataStore datastore) + public SceneObject(ulong regionHandle, Scene world, EventManager eventManager, ParcelManager parcelManager, LLUUID ownerID, uint localID, LLVector3 pos, PrimitiveBaseShape shape) { - datastore.StoreObject(this); + m_regionHandle = regionHandle; + m_world = world; + m_eventManager = eventManager; + m_parcelManager = parcelManager; + + this.Pos = pos; + this.CreateRootFromShape(ownerID, localID, shape, pos); + + registerEvents(); + } /// @@ -94,9 +99,40 @@ namespace OpenSim.Region.Environment.Scenes /// Need a null constructor for duplication public SceneObject() { - + } + public void registerEvents() + { + m_eventManager.OnBackup += new EventManager.OnBackupDelegate(ProcessBackup); + m_eventManager.OnParcelPrimCountUpdate += new EventManager.OnParcelPrimCountUpdateDelegate(ProcessParcelPrimCountUpdate); + } + public void unregisterEvents() + { + m_eventManager.OnBackup -= new EventManager.OnBackupDelegate(ProcessBackup); + m_eventManager.OnParcelPrimCountUpdate -= new EventManager.OnParcelPrimCountUpdateDelegate(ProcessParcelPrimCountUpdate); + } + /// + /// Processes backup + /// + /// + public void ProcessBackup(OpenSim.Region.Interfaces.IRegionDataStore datastore) + { + datastore.StoreObject(this); + } + + + /// + /// Sends my primitive info to the parcel manager for it to keep tally of all of the prims! + /// + private void ProcessParcelPrimCountUpdate() + { + m_parcelManager.addPrimToParcelCounts(this); + } + + + + /// /// /// @@ -105,7 +141,7 @@ namespace OpenSim.Region.Environment.Scenes /// public void CreateRootFromShape(LLUUID agentID, uint localID, PrimitiveBaseShape shape, LLVector3 pos) { - this.rootPrimitive = new Primitive(this.m_regionHandle, this.m_world, agentID, localID, true, this, this, shape, pos); + this.rootPrimitive = new Primitive(this.m_regionHandle, this.m_world,this.m_parcelManager, agentID, localID, true, this, this, shape, pos); this.children.Add(rootPrimitive); this.ChildPrimitives.Add(this.rootUUID, this.rootPrimitive); } @@ -120,7 +156,7 @@ namespace OpenSim.Region.Environment.Scenes } /// - /// + /// Copies a prim or group of prims (SceneObject) -- TODO: cleanup code /// /// A complete copy of the object public new SceneObject Copy() @@ -136,6 +172,8 @@ namespace OpenSim.Region.Environment.Scenes dupe.Rotation = this.Rotation; LLUUID rootu= dupe.rootUUID; uint rooti = dupe.rootLocalID; + + dupe.registerEvents(); return dupe; } @@ -147,6 +185,7 @@ namespace OpenSim.Region.Environment.Scenes this.children.Clear(); this.ChildPrimitives.Clear(); this.rootPrimitive = null; + unregisterEvents(); } /// @@ -256,5 +295,6 @@ namespace OpenSim.Region.Environment.Scenes client.OutPacket(proper); } + } }