Browse Source

several changes to land handling. Landchannel.cs is just a wrrapper for landmanagementmodule, so let module be it and ignore all code on landchannel.cs, to remove one day; make parcel fakeID more a thing (it is our actual parcel ID. proper globalID cannot be sent to viewers, because HG, etc.

UbitUmarov 3 years ago
parent
commit
0ee1e3b2d9

+ 0 - 1
OpenSim/Framework/AgentCircuitManager.cs

@@ -51,7 +51,6 @@ namespace OpenSim.Framework
 
         public virtual AuthenticateResponse AuthenticateSession(UUID sessionID, UUID agentID, uint circuitcode)
         {
-
             AuthenticateResponse user = new AuthenticateResponse();
             if (!m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData validcircuit) || validcircuit == null)
             {

+ 2 - 4
OpenSim/Framework/IClientAPI.cs

@@ -316,7 +316,6 @@ namespace OpenSim.Framework
                                    bool removeContribution, int parcelLocalID, int parcelArea, int parcelPrice,
                                    bool authenticated);
 
-    // We keep all this information for fraud purposes in the future.
     public delegate void MoneyBalanceRequest(IClientAPI remoteClient, UUID agentID, UUID sessionID, UUID TransactionID);
 
     public delegate void ObjectPermissions(
@@ -356,8 +355,7 @@ namespace OpenSim.Framework
 
     public delegate void SetEstateTerrainDetailTexture(IClientAPI remoteClient, int corner, UUID side);
 
-    public delegate void SetEstateTerrainTextureHeights(IClientAPI remoteClient, int corner, float lowVal, float highVal
-        );
+    public delegate void SetEstateTerrainTextureHeights(IClientAPI remoteClient, int corner, float lowVal, float highVal);
 
     public delegate void CommitEstateTerrainTextureRequest(IClientAPI remoteClient);
 
@@ -586,7 +584,7 @@ namespace OpenSim.Framework
 
     public class EntityUpdate
     {
-        private ISceneEntity m_entity;
+        private readonly ISceneEntity m_entity;
         private PrimUpdateFlags m_flags;
 
         public ISceneEntity Entity

+ 11 - 3
OpenSim/Framework/ILandObject.cs

@@ -44,6 +44,12 @@ namespace OpenSim.Framework
         bool[,] LandBitmap { get; set; }
         UUID RegionUUID { get; }
 
+        UUID GlobalID { get; }
+        UUID FakeID { get; }
+        int LocalID { get; }
+        UUID OwnerID { get; }
+        UUID GroupID { get; }
+
         /// <summary>
         /// Prim counts for this land object.
         /// </summary>
@@ -100,7 +106,8 @@ namespace OpenSim.Framework
         bool[,] BasicFullRegionLandBitmap();
 
         /// <summary>
-        /// Create a square land bitmap.
+        /// Create a land bitmap.
+        /// Square name is wrong kept bc legacy
         /// </summary>
         /// <remarks>
         /// Land co-ordinates are zero indexed.  The inputs are treated as points.  So if you want to create a bitmap
@@ -117,6 +124,7 @@ namespace OpenSim.Framework
         /// <param name="end_y"></param>
         /// <param name="set_value"></param>
         /// <returns>The bitmap created.</returns>
+        
         bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y, bool set_value = true);
 
         bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value);
@@ -143,7 +151,7 @@ namespace OpenSim.Framework
         /// <param name="AABBMin">out: parcel.AABBMin &lt;x,y,0&gt</param>
         /// <param name="AABBMax">out: parcel.AABBMax &lt;x,y,0&gt</param>
         /// <returns>New parcel bitmap</returns>
-        bool[,] RemapLandBitmap(bool[,] bitmap_base, Vector2 displacement, float rotationDegrees, Vector2 boundingOrigin, Vector2 boundingSize, Vector2 regionSize, out bool isEmptyNow, out Vector3 AABBMin, out Vector3 AABBMax);
+        bool[,] RemapLandBitmap(bool[,] bitmap_base, Vector2 displacement, float rotationDegrees, Vector2 boundingOrigin, Vector2 boundingSize, Vector2 regionSize, out bool isEmptyNow);
 
         /// <summary>
         /// Clears any parcel data in bitmap_base where there exists parcel data in bitmap_new. In other words the parcel data
@@ -155,7 +163,7 @@ namespace OpenSim.Framework
         /// <param name="AABBMin">out: parcel.AABBMin &lt;x,y,0&gt;</param>
         /// <param name="AABBMax">out: parcel.AABBMax &lt;x,y,0&gt</param>
         /// <returns>New parcel bitmap</returns>
-        bool[,] RemoveFromLandBitmap(bool[,] bitmap_base, bool[,] bitmap_new, out bool isEmptyNow, out Vector3 AABBMin, out Vector3 AABBMax);
+        bool[,] RemoveFromLandBitmap(bool[,] bitmap_base, bool[,] bitmap_new, out bool isEmptyNow);
 
         byte[] ConvertLandBitmapToBytes();
         bool[,] ConvertBytesToLandBitmap(bool overrideRegionSize = false);

+ 1 - 23
OpenSim/Framework/LandData.cs

@@ -46,11 +46,6 @@ namespace OpenSim.Framework
     /// </summary>
     public class LandData
     {
-        // use only one serializer to give the runtime a chance to
-        // optimize it (it won't do that if you use a new instance
-        // every time)
-        private static XmlSerializer serializer = new XmlSerializer(typeof(LandData));
-
         private Vector3 _AABBMax = new Vector3();
         private Vector3 _AABBMin = new Vector3();
         private int _area = 0;
@@ -382,7 +377,7 @@ namespace OpenSim.Framework
         }
 
         /// <summary>
-        /// jp2 data for the image representative of the parcel in the parcel dialog
+        /// parcel shape in bits per ocupied location
         /// </summary>
         public byte[] Bitmap
         {
@@ -837,22 +832,5 @@ namespace OpenSim.Framework
 
             return landData;
         }
-
-//        public void ToXml(XmlWriter xmlWriter)
-//        {
-//            serializer.Serialize(xmlWriter, this);
-//        }
-
-        /// <summary>
-        /// Restore a LandData object from the serialized xml representation.
-        /// </summary>
-        /// <param name="xmlReader"></param>
-        /// <returns></returns>
-//        public static LandData FromXml(XmlReader xmlReader)
-//        {
-//            LandData land = (LandData)serializer.Deserialize(xmlReader);
-//
-//            return land;
-//        }
     }
 }

+ 4 - 6
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs

@@ -10663,12 +10663,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             if (propertiesRequest.AgentData.SessionID != SessionId || propertiesRequest.AgentData.AgentID != AgentId)
                 return;
 
-            OnParcelPropertiesRequest?.Invoke((int)Math.Round(propertiesRequest.ParcelData.West),
-                                               (int)Math.Round(propertiesRequest.ParcelData.South),
-                                               (int)Math.Round(propertiesRequest.ParcelData.East),
-                                               (int)Math.Round(propertiesRequest.ParcelData.North),
-                                               propertiesRequest.ParcelData.SequenceID,
-                                               propertiesRequest.ParcelData.SnapSelection, this);
+            ParcelPropertiesRequestPacket.ParcelDataBlock pdb = propertiesRequest.ParcelData;
+            OnParcelPropertiesRequest?.Invoke((int)Math.Round(pdb.West), (int)Math.Round(pdb.South),
+                                              (int)Math.Round(pdb.East), (int)Math.Round(pdb.North),
+                                              pdb.SequenceID, pdb.SnapSelection, this);
         }
 
         private void HandleParcelDivide(Packet Pack)

+ 2 - 8
OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs

@@ -765,8 +765,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
                 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
                 bool overrideRegionSize = true;  //use the src land parcel data size not the dst region size
                 bool isEmptyNow;
-                Vector3 AABBMin;
-                Vector3 AABBMax;
 
                 // create a new LandObject that we can use to manipulate the incoming source parcel data
                 // this is ok, but just beware that some of the LandObject functions (that we haven't used here) still
@@ -786,7 +784,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
                 //   parcel.Name, parcel.GlobalID, parcel.LocalID);
                 //landObject.DebugLandBitmap(srcLandBitmap);
 
-                bool[,] dstLandBitmap = landObject.RemapLandBitmap(srcLandBitmap, displacement, m_rotation, boundingOrigin, boundingSize, regionSize, out isEmptyNow, out AABBMin, out AABBMax);
+                bool[,] dstLandBitmap = landObject.RemapLandBitmap(srcLandBitmap, displacement, m_rotation, boundingOrigin, boundingSize, regionSize, out isEmptyNow);
                 if (isEmptyNow)
                 {
                     m_log.WarnFormat("[ARCHIVER]: Not adding destination parcel {0} with GlobalID: {1} LocalID: {2} because, after applying rotation, bounding and displacement, it has no claimed land.",
@@ -799,8 +797,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
 
                 landObject.LandBitmap = dstLandBitmap;
                 parcel.Bitmap = landObject.ConvertLandBitmapToBytes();
-                parcel.AABBMin = AABBMin;
-                parcel.AABBMax = AABBMax;
 
                 if (domerge)
                 {
@@ -814,7 +810,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
                         if (parcels[i] != null)
                         {
                             bool[,] modLandBitmap = parcels[i].ConvertBytesToLandBitmap(overrideRegionSize);
-                            modLandBitmap = parcels[i].RemoveFromLandBitmap(modLandBitmap, dstLandBitmap, out isEmptyNow, out AABBMin, out AABBMax);
+                            modLandBitmap = parcels[i].RemoveFromLandBitmap(modLandBitmap, dstLandBitmap, out isEmptyNow);
                             if (isEmptyNow)
                             {
                                 parcels[i] = null;
@@ -823,8 +819,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
                             {
                                 parcels[i].LandBitmap = modLandBitmap;
                                 parcels[i].LandData.Bitmap = parcels[i].ConvertLandBitmapToBytes();
-                                parcels[i].LandData.AABBMin = AABBMin;
-                                parcels[i].LandData.AABBMax = AABBMax;
                             }
                         }
                     }

+ 19 - 87
OpenSim/Region/CoreModules/World/Land/LandChannel.cs

@@ -103,32 +103,17 @@ namespace OpenSim.Region.CoreModules.World.Land
 
         public ILandObject GetLandObject(float x_float, float y_float)
         {
-            if (m_landManagementModule != null)
-            {
-                return m_landManagementModule.GetLandObject(x_float, y_float);
-            }
-
-            ILandObject obj = new LandObject(UUID.Zero, false, m_scene);
-            obj.LandData.Name = "NO LAND";
-            return obj;
+            return m_landManagementModule != null ? m_landManagementModule.GetLandObject(x_float, y_float) : null;
         }
 
         public ILandObject GetLandObject(int localID)
         {
-            if (m_landManagementModule != null)
-            {
-                return m_landManagementModule.GetLandObject(localID);
-            }
-            return null;
+            return m_landManagementModule != null ? m_landManagementModule.GetLandObject(localID) : null;
         }
 
         public ILandObject GetLandObject(UUID GlobalID)
         {
-            if (m_landManagementModule != null)
-            {
-                return m_landManagementModule.GetLandObject(GlobalID);
-            }
-            return null;
+                return m_landManagementModule != null ? m_landManagementModule.GetLandObject(GlobalID) : null;
         }
 
         public ILandObject GetLandObject(Vector3 position)
@@ -138,130 +123,77 @@ namespace OpenSim.Region.CoreModules.World.Land
 
         public ILandObject GetLandObject(int x, int y)
         {
-            if (m_landManagementModule != null)
-            {
-                return m_landManagementModule.GetLandObject(x, y);
-            }
-
-            ILandObject obj = new LandObject(UUID.Zero, false, m_scene);
-            obj.LandData.Name = "NO LAND";
-            return obj;
+            return m_landManagementModule != null ? m_landManagementModule.GetLandObject(x, y) : null;
         }
 
         public ILandObject GetLandObjectClipedXY(float x, float y)
         {
-            if (m_landManagementModule != null)
-            {
-                return m_landManagementModule.GetLandObjectClipedXY(x, y);
-            }
-            return null;
+            return m_landManagementModule != null ? m_landManagementModule.GetLandObjectClipedXY(x, y) : null;
         }
 
         public List<ILandObject> AllParcels()
         {
-            if (m_landManagementModule != null)
-            {
-                return m_landManagementModule.AllParcels();
-            }
-
-            return new List<ILandObject>();
+            return m_landManagementModule != null ? m_landManagementModule.AllParcels() : new List<ILandObject>();
         }
 
         public void Clear(bool setupDefaultParcel)
         {
-            if (m_landManagementModule != null)
-                m_landManagementModule.Clear(setupDefaultParcel);
+             m_landManagementModule?.Clear(setupDefaultParcel);
         }
 
         public List<ILandObject> ParcelsNearPoint(Vector3 position)
         {
-            if (m_landManagementModule != null)
-            {
-                return m_landManagementModule.ParcelsNearPoint(position);
-            }
-
-            return new List<ILandObject>();
+            return m_landManagementModule != null ? m_landManagementModule.ParcelsNearPoint(position) : new List<ILandObject>();
         }
 
         public bool IsForcefulBansAllowed()
         {
-            if (m_landManagementModule != null)
-            {
-                return m_landManagementModule.AllowedForcefulBans;
-            }
-
-            return false;
+            return m_landManagementModule != null ? m_landManagementModule.AllowedForcefulBans : false;
         }
 
         public void UpdateLandObject(int localID, LandData data)
         {
-            if (m_landManagementModule != null)
-            {
-                m_landManagementModule.UpdateLandObject(localID, data);
-            }
+            m_landManagementModule?.UpdateLandObject(localID, data);
         }
 
         public void SendParcelsOverlay(IClientAPI client)
         {
-            if (m_landManagementModule != null)
-            {
-                m_landManagementModule.SendParcelOverlay(client);
-            }
+            m_landManagementModule?.SendParcelOverlay(client);
         }
 
         public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
         {
-            if (m_landManagementModule != null)
-            {
-                m_landManagementModule.Join(start_x, start_y, end_x, end_y, attempting_user_id);
-            }
+            m_landManagementModule?.Join(start_x, start_y, end_x, end_y, attempting_user_id);
         }
 
         public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
         {
-            if (m_landManagementModule != null)
-            {
-                m_landManagementModule.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
-            }
+            m_landManagementModule?.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
         }
 
         public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
         {
-            if (m_landManagementModule != null)
-            {
-                m_landManagementModule.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient);
-            }
+            m_landManagementModule?.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient);
         }
 
         public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel)
         {
-            if (m_landManagementModule != null)
-            {
-                m_landManagementModule.setParcelObjectMaxOverride(overrideDel);
-            }
+            m_landManagementModule?.setParcelObjectMaxOverride(overrideDel);
         }
 
         public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel)
         {
-            if (m_landManagementModule != null)
-            {
-                m_landManagementModule.setSimulatorObjectMaxOverride(overrideDel);
-            }
+            m_landManagementModule?.setSimulatorObjectMaxOverride(overrideDel);
         }
 
         public void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)
         {
-            if (m_landManagementModule != null)
-            {
-                m_landManagementModule.setParcelOtherCleanTime(remoteClient, localID, otherCleanTime);
-            }
+            m_landManagementModule?.SetParcelOtherCleanTime(remoteClient, localID, otherCleanTime);
         }
+
         public void sendClientInitialLandInfo(IClientAPI remoteClient, bool overlay)
         {
-            if (m_landManagementModule != null)
-            {
-                m_landManagementModule.sendClientInitialLandInfo(remoteClient, overlay);
-            }
+            m_landManagementModule?.sendClientInitialLandInfo(remoteClient, overlay);
         }
 
         public void ClearAllEnvironments()

+ 134 - 37
OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs

@@ -64,7 +64,7 @@ namespace OpenSim.Region.CoreModules.World.Land
     }
 
     [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LandManagementModule")]
-    public class LandManagementModule : INonSharedRegionModule
+    public class LandManagementModule : INonSharedRegionModule , ILandChannel
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
         private static readonly string LogHeader = "[LAND MANAGEMENT MODULE]";
@@ -75,8 +75,12 @@ namespace OpenSim.Region.CoreModules.World.Land
 
         public const int LandUnit = 4;
 
-        private LandChannel landChannel;
         private Scene m_scene;
+        //private LandChannel m_landChannel;
+
+        private ulong m_regionHandler;
+        private int m_regionSizeX;
+        private int m_regionSizeY;
 
         protected IGroupsModule m_groupManager;
         protected IUserManagement m_userManager;
@@ -91,11 +95,10 @@ namespace OpenSim.Region.CoreModules.World.Land
         /// <value>
         /// Land objects keyed by local id
         /// </value>
-//        private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
 
-        //ubit: removed the readonly so i can move it around
-        private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
-        private Dictionary<UUID, int> m_landUUIDList = new Dictionary<UUID, int>();
+        private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
+        private readonly Dictionary<UUID, int> m_landGlobalIDs = new Dictionary<UUID, int>();
+        private readonly Dictionary<UUID, int> m_landFakeIDs = new Dictionary<UUID, int>();
 
         private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
 
@@ -161,9 +164,12 @@ namespace OpenSim.Region.CoreModules.World.Land
         public void AddRegion(Scene scene)
         {
             m_scene = scene;
-            m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
+            m_regionHandler = m_scene.RegionInfo.RegionHandle;
+            m_regionSizeX = (int)m_scene.RegionInfo.RegionSizeX;
+            m_regionSizeY = (int)m_scene.RegionInfo.RegionSizeY;
+            m_landIDList = new int[m_regionSizeX / LandUnit, m_regionSizeY / LandUnit];
 
-            landChannel = new LandChannel(scene, this);
+            //m_landChannel = new LandChannel(scene, this);
 
             m_scene.EventManager.OnObjectAddedToScene += EventManagerOnParcelPrimCountAdd;
             m_scene.EventManager.OnParcelPrimCountAdd += EventManagerOnParcelPrimCountAdd;
@@ -186,7 +192,8 @@ namespace OpenSim.Region.CoreModules.World.Land
 
             lock (m_scene)
             {
-                m_scene.LandChannel = (ILandChannel)landChannel;
+                //m_scene.LandChannel = m_landChannel;
+                m_scene.LandChannel = this;
             }
 
             RegisterCommands();
@@ -268,8 +275,13 @@ namespace OpenSim.Region.CoreModules.World.Land
             {
                 if (m_landList.TryGetValue(local_id, out land))
                 {
+                    m_landGlobalIDs.Remove(land.LandData.GlobalID);
+                    if (land.LandData.FakeID != UUID.Zero)
+                        m_landFakeIDs.Remove(land.LandData.FakeID);
                     land.LandData = newData;
-                    m_landUUIDList[newData.GlobalID] = local_id;
+                    m_landGlobalIDs[newData.GlobalID] = local_id;
+                    if (newData.FakeID != UUID.Zero)
+                        m_landFakeIDs[newData.FakeID] = local_id;
                 }
             }
 
@@ -277,6 +289,11 @@ namespace OpenSim.Region.CoreModules.World.Land
                 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, land);
         }
 
+        public bool IsForcefulBansAllowed()
+        {
+            return AllowedForcefulBans;
+        }
+
         public bool AllowedForcefulBans
         {
             get { return m_allowedForcefulBans; }
@@ -295,10 +312,11 @@ namespace OpenSim.Region.CoreModules.World.Land
                     parcel.Clear();
 
                 m_landList.Clear();
-                m_landUUIDList.Clear();
+                m_landGlobalIDs.Clear();
+                m_landFakeIDs.Clear();
                 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
 
-                m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
+                m_landIDList = new int[m_regionSizeX / LandUnit, m_regionSizeY / LandUnit];
             }
         }
 
@@ -312,8 +330,7 @@ namespace OpenSim.Region.CoreModules.World.Land
 
             ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
 
-            fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
-                                            (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
+            fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, m_regionSizeX, m_regionSizeY));
             LandData ldata = fullSimParcel.LandData;
             ldata.SimwideArea = ldata.Area;
             ldata.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@@ -795,9 +812,10 @@ namespace OpenSim.Region.CoreModules.World.Land
                         }
                     }
                 }
-
+                
                 m_landList.Add(newLandLocalID, new_land);
-                m_landUUIDList[new_land.LandData.GlobalID] = newLandLocalID;
+                m_landGlobalIDs[new_land.LandData.GlobalID] = newLandLocalID;
+                m_landFakeIDs[new_land.LandData.FakeID] = newLandLocalID;
                 m_lastLandLocalID++;
             }
 
@@ -836,7 +854,8 @@ namespace OpenSim.Region.CoreModules.World.Land
                 if(land != null && land.LandData != null)
                 {
                     landGlobalID = land.LandData.GlobalID;
-                    m_landUUIDList.Remove(landGlobalID);
+                    m_landGlobalIDs.Remove(landGlobalID);
+                    m_landFakeIDs.Remove(land.LandData.FakeID);
                 }
             }
 
@@ -857,7 +876,7 @@ namespace OpenSim.Region.CoreModules.World.Land
             lock (m_landList)
             {
                 landworkList = m_landList;
-                m_landList = new Dictionary<int, ILandObject>();
+                m_landList.Clear();
             }
 
             // this 2 methods have locks (now)
@@ -873,7 +892,6 @@ namespace OpenSim.Region.CoreModules.World.Land
                 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
             }
             landworkList.Clear();
-
         }
 
         private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -902,19 +920,44 @@ namespace OpenSim.Region.CoreModules.World.Land
             lock (m_landList)
             {
                 int lid = -1;
-                if(m_landUUIDList.TryGetValue(globalID, out lid) && lid >= 0)
+                if (m_landGlobalIDs.TryGetValue(globalID, out lid) && lid >= 0)
                 {
                     if (m_landList.ContainsKey(lid))
                     {
                         return m_landList[lid];
                     }
                     else
-                        m_landUUIDList.Remove(globalID); // auto heal
+                        m_landGlobalIDs.Remove(globalID); // auto heal
                 }
             }
             return null;
         }
 
+        public ILandObject GetLandObjectByfakeID(UUID fakeID)
+        {
+            lock (m_landList)
+            {
+                int lid = -1;
+                if (m_landFakeIDs.TryGetValue(fakeID, out lid) && lid >= 0)
+                {
+                    if (m_landList.ContainsKey(lid))
+                    {
+                        return m_landList[lid];
+                    }
+                    else
+                        m_landFakeIDs.Remove(fakeID); // auto heal
+                }
+            }
+            if(Util.ParseFakeParcelID(fakeID, out ulong rhandle, out uint x, out uint y) && rhandle == m_regionHandler)
+            {
+                ILandObject ret = GetLandObjectClipedXY(x, y);
+                if(ret != null)
+                    m_landFakeIDs[fakeID] = ret.LandData.LocalID;
+                return ret;
+            }
+            return null;
+        }
+
         public ILandObject GetLandObject(int parcelLocalID)
         {
             lock (m_landList)
@@ -938,6 +981,11 @@ namespace OpenSim.Region.CoreModules.World.Land
             return GetLandObject((int)x_float, (int)y_float, true);
         }
 
+        public ILandObject GetLandObject(Vector3 position)
+        {
+            return GetLandObject(position.X, position.Y);
+        }
+
         // if x,y is off region this will return the parcel at cliped x,y
         // as did code it replaces
         public ILandObject GetLandObjectClipedXY(float x, float y)
@@ -946,14 +994,14 @@ namespace OpenSim.Region.CoreModules.World.Land
             int avx = (int)x;
             if (avx < 0)
                 avx = 0;
-            else if (avx >= m_scene.RegionInfo.RegionSizeX)
-                avx = (int)Constants.RegionSize - 1;
+            else if (avx >= m_regionSizeX)
+                avx = m_regionSizeX - 1;
 
             int avy = (int)y;
             if (avy < 0)
                 avy = 0;
-            else if (avy >= m_scene.RegionInfo.RegionSizeY)
-                avy = (int)Constants.RegionSize - 1;
+            else if (avy >= m_regionSizeY)
+                avy = m_regionSizeY - 1;
 
             lock (m_landIDList)
             {
@@ -977,7 +1025,7 @@ namespace OpenSim.Region.CoreModules.World.Land
 
         public ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds)
         {
-            if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
+            if (x >= m_regionSizeX || y >= m_regionSizeY || x < 0 || y < 0)
             {
                 // These exceptions here will cause a lot of complaints from the users specifically because
                 // they happen every time at border crossings
@@ -1021,6 +1069,21 @@ namespace OpenSim.Region.CoreModules.World.Land
             }
         }
 
+        public ILandObject GetLandObjectinLandUnitsInt(int x, int y)
+        {
+            lock (m_landIDList)
+            {
+                try
+                {
+                    return m_landList[m_landIDList[x, y]];
+                }
+                catch (IndexOutOfRangeException)
+                {
+                    return null;
+                }
+            }
+        }
+
         public int GetLandObjectIDinLandUnits(int x, int y)
         {
             lock (m_landIDList)
@@ -1042,7 +1105,7 @@ namespace OpenSim.Region.CoreModules.World.Land
             bool[,] ret = new bool[m_landIDList.GetLength(0), m_landIDList.GetLength(1)];
 
             for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
-                for (int yy = 0; yy < m_landIDList.GetLength(0); yy++)
+                for (int yy = 0; yy < m_landIDList.GetLength(1); yy++)
                     if (m_landIDList[xx, yy] == landID)
                         ret[xx, yy] = true;
 
@@ -1319,6 +1382,12 @@ namespace OpenSim.Region.CoreModules.World.Land
 
         #region Parcel Updating
 
+        //legacy name
+        public void SendParcelsOverlay(IClientAPI client)
+        {
+            SendParcelsOverlay(client);
+        }
+
         /// <summary>
         /// Send the parcel overlay blocks to the client. 
         /// </summary>
@@ -1337,12 +1406,12 @@ namespace OpenSim.Region.CoreModules.World.Land
             int byteArrayCount = 0;
             int sequenceID = 0;
 
-            int sx = (int)m_scene.RegionInfo.RegionSizeX / LandUnit;
+            int sx = m_regionSizeX / LandUnit;
             byte curByte;
             byte tmpByte;
 
             // Layer data is in LandUnit (4m) chunks
-            for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / LandUnit; ++y)
+            for (int y = 0; y < m_regionSizeY / LandUnit; ++y)
             {
                 for (int x = 0; x < sx;)
                 {
@@ -1471,13 +1540,35 @@ namespace OpenSim.Region.CoreModules.World.Land
         public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
                                                     bool snap_selection, IClientAPI remote_client)
         {
+            if (m_landList.Count == 0 || m_landIDList == null)
+                return;
+
+            if (start_x < 0 || start_y < 0 || end_x < 0 || end_y < 0)
+                return;
+            if (start_x >= m_regionSizeX || start_y >= m_regionSizeX || end_x >= m_regionSizeY || end_y >= m_regionSizeY)
+                return;
+
+            if (end_x - start_x <= LandUnit &&
+                end_y - start_y <= LandUnit)
+            {
+                ILandObject parcel = GetLandObject(start_x, start_y);
+                if(parcel != null)
+                    parcel.SendLandProperties(sequence_id, snap_selection, LandChannel.LAND_RESULT_SINGLE, remote_client);
+                return;
+            }
+
+            start_x /= LandUnit;
+            start_y /= LandUnit;
+            end_x /= LandUnit;
+            end_y /= LandUnit;
+
             //Get the land objects within the bounds
             Dictionary<int, ILandObject> temp = new Dictionary<int, ILandObject>();
-            for (int x = start_x; x < end_x; x += LandUnit)
+            for (int x = start_x; x < end_x; ++x)
             {
-                for (int y = start_y; y < end_y; y += LandUnit)
+                for (int y = start_y; y < end_y; ++y)
                 {
-                    ILandObject currentParcel = GetLandObject(x, y);
+                    ILandObject currentParcel = GetLandObjectinLandUnits(x, y);
 
                     if (currentParcel != null)
                     {
@@ -1485,7 +1576,6 @@ namespace OpenSim.Region.CoreModules.World.Land
                         {
                             if (!currentParcel.IsBannedFromLand(remote_client.AgentId))
                             {
-                                currentParcel.ForceUpdateLandInfo();
                                 temp[currentParcel.LandData.LocalID] = currentParcel;
                             }
                         }
@@ -1752,9 +1842,9 @@ namespace OpenSim.Region.CoreModules.World.Land
                     IncomingLandObjectFromStorage(data[i]);
 
                 // Layer data is in LandUnit (4m) chunks
-                for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
+                for (int y = 0; y < m_regionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
                 {
-                    for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
+                    for (int x = 0; x < m_regionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
                     {
                         if (m_landIDList[x, y] == 0)
                         {
@@ -2216,7 +2306,7 @@ namespace OpenSim.Region.CoreModules.World.Land
                 m_log.Debug("[LAND MANAGEMENT MODULE]: got no parcelinfo; not sending");
         }
 
-        public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)
+        public void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)
         {
             ILandObject land = null;
             lock (m_landList)
@@ -2479,6 +2569,13 @@ namespace OpenSim.Region.CoreModules.World.Land
             }
         }
 
+        public void ClearAllEnvironments()
+        {
+            List<ILandObject> parcels = AllParcels();
+            for (int i = 0; i < parcels.Count; ++i)
+                parcels[i].StoreEnvironment(null);
+        }
+
         /// <summary>
         /// Sets the Home Point.   The LoginService uses this to know where to put a user when they log-in
         /// </summary>
@@ -2490,7 +2587,7 @@ namespace OpenSim.Region.CoreModules.World.Land
         public virtual void ClientOnSetHome(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
         {
             // Let's find the parcel in question
-            ILandObject land = landChannel.GetLandObject(position);
+            ILandObject land = GetLandObject(position);
             if (land == null || m_scene.GridUserService == null)
             {
                 m_Dialog.SendAlertToUser(remoteClient, "Set Home request failed.");

+ 60 - 52
OpenSim/Region/CoreModules/World/Land/LandObject.cs

@@ -86,6 +86,46 @@ namespace OpenSim.Region.CoreModules.World.Land
             set { m_landData = value; }
         }
 
+        public UUID GlobalID
+        {
+            get
+            {
+                return m_landData == null ? UUID.Zero : m_landData.GlobalID;
+            }
+        }
+
+        public UUID FakeID
+        {
+            get
+            {
+                return m_landData == null ? UUID.Zero : m_landData.FakeID;
+            }
+        }
+
+        public UUID OwnerID
+        {
+            get
+            {
+                return m_landData == null ? UUID.Zero : m_landData.OwnerID;
+            }
+        }
+
+        public UUID GroupID
+        {
+            get
+            {
+                return m_landData == null ? UUID.Zero : m_landData.GroupID;
+            }
+        }
+
+        public int LocalID
+        {
+            get
+            {
+                return m_landData == null ? -1 : m_landData.LocalID;
+            }
+        }
+
         public IPrimCounts PrimCounts { get; set; }
 
         public UUID RegionUUID
@@ -312,7 +352,7 @@ namespace OpenSim.Region.CoreModules.World.Land
         {
             if(m_scene != null)
                  m_scene.EventManager.OnFrame -= OnFrame;
-            LandData = null;     
+            LandData = null;
         }
 
 
@@ -1206,14 +1246,7 @@ namespace OpenSim.Region.CoreModules.World.Land
 
         public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y, bool set_value = true)
         {
-            // Empty bitmap for the whole region
-            bool[,] tempBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
-            tempBitmap.Initialize();
-
-            // Fill the bitmap square area specified by state and end
-            tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, set_value);
-            // m_log.DebugFormat("{0} GetSquareLandBitmap. tempBitmapSize=<{1},{2}>",
-            //                         LogHeader, tempBitmap.GetLength(0), tempBitmap.GetLength(1));
+            bool[,] tempBitmap = ModifyLandBitmapSquare(null, start_x, start_y, end_x, end_y, set_value);
             return tempBitmap;
         }
 
@@ -1230,18 +1263,26 @@ namespace OpenSim.Region.CoreModules.World.Land
         public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
                                               bool set_value)
         {
-            int x, y;
-            for (y = 0; y < land_bitmap.GetLength(1); y++)
+            if(land_bitmap == null)
+            {
+                land_bitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
+                if(!set_value)
+                    return land_bitmap;
+            }
+
+            start_x /= landUnit;
+            end_x /= landUnit;
+            start_y /= landUnit;
+            end_y /= landUnit;
+
+            for (int x = start_x; x < end_x; ++x)
             {
-                for (x = 0; x < land_bitmap.GetLength(0); x++)
+                for (int y = start_y; y < end_y; ++y)
                 {
-                    if (x >= start_x / landUnit && x < end_x / landUnit
-                        && y >= start_y / landUnit && y < end_y / landUnit)
-                    {
-                        land_bitmap[x, y] = set_value;
-                    }
+                    land_bitmap[x, y] = set_value;
                 }
             }
+
             // m_log.DebugFormat("{0} ModifyLandBitmapSquare. startXY=<{1},{2}>, endXY=<{3},{4}>, val={5}, landBitmapSize=<{6},{7}>",
             //                         LogHeader, start_x, start_y, end_x, end_y, set_value, land_bitmap.GetLength(0), land_bitmap.GetLength(1));
             return land_bitmap;
@@ -1288,7 +1329,7 @@ namespace OpenSim.Region.CoreModules.World.Land
         /// <param name="AABBMin">out: parcel.AABBMin &lt;x,y,0&gt</param>
         /// <param name="AABBMax">out: parcel.AABBMax &lt;x,y,0&gt</param>
         /// <returns>New parcel bitmap</returns>
-        public bool[,] RemapLandBitmap(bool[,] bitmap_base, Vector2 displacement, float rotationDegrees, Vector2 boundingOrigin, Vector2 boundingSize, Vector2 regionSize, out bool isEmptyNow, out Vector3 AABBMin, out Vector3 AABBMax)
+        public bool[,] RemapLandBitmap(bool[,] bitmap_base, Vector2 displacement, float rotationDegrees, Vector2 boundingOrigin, Vector2 boundingSize, Vector2 regionSize, out bool isEmptyNow)
         {
             // get the size of the incoming bitmap
             int baseX = bitmap_base.GetLength(0);
@@ -1387,10 +1428,6 @@ namespace OpenSim.Region.CoreModules.World.Land
             //                            baseX, baseY, dispX, dispY, radianRotation, offsetX, offsetY, startX, startY, endX, endY, cosR, sinR, newX, newY);
 
             isEmptyNow = true;
-            int minX = newX;
-            int minY = newY;
-            int maxX = 0;
-            int maxY = 0;
 
             int dx, dy;
             for (y = startY; y < endY; y++)
@@ -1407,10 +1444,6 @@ namespace OpenSim.Region.CoreModules.World.Land
                             {
                                 bitmap_new[dx, dy] = true;
                                 isEmptyNow = false;
-                                if (dx < minX) minX = dx;
-                                if (dy < minY) minY = dy;
-                                if (dx > maxX) maxX = dx;
-                                if (dy > maxY) maxY = dy;
                             }
                         }
                         catch (Exception)   //just in case we've still not taken care of every way the arrays might go out of bounds! ;)
@@ -1420,15 +1453,6 @@ namespace OpenSim.Region.CoreModules.World.Land
                     }
                 }
             }
-            if (isEmptyNow)
-            {
-                //m_log.DebugFormat("{0} RemapLandBitmap: Land bitmap is marked as Empty", LogHeader);
-                minX = 0;
-                minY = 0;
-            }
-
-            AABBMin = new Vector3(minX * landUnit, minY * landUnit, 0);
-            AABBMax = new Vector3(maxX * landUnit, maxY * landUnit, 0);
             return bitmap_new;
         }
 
@@ -1442,7 +1466,7 @@ namespace OpenSim.Region.CoreModules.World.Land
         /// <param name="AABBMin">out: parcel.AABBMin &lt;x,y,0&gt</param>
         /// <param name="AABBMax">out: parcel.AABBMax &lt;x,y,0&gt</param>
         /// <returns>New parcel bitmap</returns>
-        public bool[,] RemoveFromLandBitmap(bool[,] bitmap_base, bool[,] bitmap_new, out bool isEmptyNow, out Vector3 AABBMin, out Vector3 AABBMax)
+        public bool[,] RemoveFromLandBitmap(bool[,] bitmap_base, bool[,] bitmap_new, out bool isEmptyNow)
         {
             // get the size of the incoming bitmaps
             int baseX = bitmap_base.GetLength(0);
@@ -1457,10 +1481,6 @@ namespace OpenSim.Region.CoreModules.World.Land
             }
 
             isEmptyNow = true;
-            int minX = baseX;
-            int minY = baseY;
-            int maxX = 0;
-            int maxY = 0;
 
             for (int x = 0; x < baseX; x++)
             {
@@ -1470,21 +1490,9 @@ namespace OpenSim.Region.CoreModules.World.Land
                     if (bitmap_base[x, y])
                     {
                         isEmptyNow = false;
-                        if (x < minX) minX = x;
-                        if (y < minY) minY = y;
-                        if (x > maxX) maxX = x;
-                        if (y > maxY) maxY = y;
                     }
                 }
             }
-            if (isEmptyNow)
-            {
-                //m_log.DebugFormat("{0} RemoveFromLandBitmap: Land bitmap is marked as Empty", LogHeader);
-                minX = 0;
-                minY = 0;
-            }
-            AABBMin = new Vector3(minX * landUnit, minY * landUnit, 0);
-            AABBMax = new Vector3(maxX * landUnit, maxY * landUnit, 0);
             return bitmap_base;
         }