aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Land
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Land')
-rw-r--r--OpenSim/Region/CoreModules/World/Land/DwellModule.cs27
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandChannel.cs62
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs1333
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs886
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs177
-rw-r--r--OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs40
-rw-r--r--OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs224
7 files changed, 1831 insertions, 918 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/DwellModule.cs b/OpenSim/Region/CoreModules/World/Land/DwellModule.cs
index 70c6028..22480e6 100644
--- a/OpenSim/Region/CoreModules/World/Land/DwellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/DwellModule.cs
@@ -53,7 +53,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
53namespace OpenSim.Region.CoreModules.World.Land 53namespace OpenSim.Region.CoreModules.World.Land
54{ 54{
55 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DefaultDwellModule")] 55 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DefaultDwellModule")]
56 public class DefaultDwellModule : IDwellModule, INonSharedRegionModule 56 public class DefaultDwellModule : INonSharedRegionModule, IDwellModule
57 { 57 {
58 private Scene m_scene; 58 private Scene m_scene;
59 private IConfigSource m_Config; 59 private IConfigSource m_Config;
@@ -88,16 +88,21 @@ namespace OpenSim.Region.CoreModules.World.Land
88 return; 88 return;
89 89
90 m_scene = scene; 90 m_scene = scene;
91 91 m_scene.RegisterModuleInterface<IDwellModule>(this);
92 m_scene.EventManager.OnNewClient += OnNewClient;
93 } 92 }
94 93
95 public void RegionLoaded(Scene scene) 94 public void RegionLoaded(Scene scene)
96 { 95 {
96 if (!m_Enabled)
97 return;
98 m_scene.EventManager.OnNewClient += OnNewClient;
97 } 99 }
98 100
99 public void RemoveRegion(Scene scene) 101 public void RemoveRegion(Scene scene)
100 { 102 {
103 if (!m_Enabled)
104 return;
105 m_scene.EventManager.OnNewClient -= OnNewClient;
101 } 106 }
102 107
103 public void Close() 108 public void Close()
@@ -115,12 +120,26 @@ namespace OpenSim.Region.CoreModules.World.Land
115 if (parcel == null) 120 if (parcel == null)
116 return; 121 return;
117 122
118 client.SendParcelDwellReply(localID, parcel.LandData.GlobalID, parcel.LandData.Dwell); 123 LandData land = parcel.LandData;
124 if(land!= null)
125 client.SendParcelDwellReply(localID, land.GlobalID, land.Dwell);
119 } 126 }
120 127
128
121 public int GetDwell(UUID parcelID) 129 public int GetDwell(UUID parcelID)
122 { 130 {
131 ILandObject parcel = m_scene.LandChannel.GetLandObject(parcelID);
132 if (parcel != null && parcel.LandData != null)
133 return (int)(parcel.LandData.Dwell);
134 return 0;
135 }
136
137 public int GetDwell(LandData land)
138 {
139 if (land != null)
140 return (int)(land.Dwell);
123 return 0; 141 return 0;
124 } 142 }
143
125 } 144 }
126} 145}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
index 73c592d..5ff063b 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
@@ -37,26 +37,37 @@ namespace OpenSim.Region.CoreModules.World.Land
37 { 37 {
38 #region Constants 38 #region Constants
39 39
40 public const float BAN_LINE_SAFETY_HEIGHT = 100;
40 //Land types set with flags in ParcelOverlay. 41 //Land types set with flags in ParcelOverlay.
41 //Only one of these can be used. 42 //Only one of these can be used.
42 public const float BAN_LINE_SAFETY_HIEGHT = 100; 43
43 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = 128; //Equals 10000000
44 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = 64; //Equals 01000000
45 44
46 //RequestResults (I think these are right, they seem to work): 45 //RequestResults (I think these are right, they seem to work):
47 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land 46 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land
48 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land 47 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land
49 48
50 //ParcelSelectObjects 49 //ParcelSelectObjects
50 public const int LAND_SELECT_OBJECTS_OWNER = 2;
51 public const int LAND_SELECT_OBJECTS_GROUP = 4; 51 public const int LAND_SELECT_OBJECTS_GROUP = 4;
52 public const int LAND_SELECT_OBJECTS_OTHER = 8; 52 public const int LAND_SELECT_OBJECTS_OTHER = 8;
53 public const int LAND_SELECT_OBJECTS_OWNER = 2; 53
54 public const byte LAND_TYPE_IS_BEING_AUCTIONED = 5; //Equals 00000101 54
55 public const byte LAND_TYPE_IS_FOR_SALE = 4; //Equals 00000100 55 public const byte LAND_TYPE_PUBLIC = 0; //Equals 00000000
56 public const byte LAND_TYPE_OWNED_BY_GROUP = 2; //Equals 00000010 56 // types 1 to 7 are exclusive
57 public const byte LAND_TYPE_OWNED_BY_OTHER = 1; //Equals 00000001 57 public const byte LAND_TYPE_OWNED_BY_OTHER = 1; //Equals 00000001
58 public const byte LAND_TYPE_OWNED_BY_GROUP = 2; //Equals 00000010
58 public const byte LAND_TYPE_OWNED_BY_REQUESTER = 3; //Equals 00000011 59 public const byte LAND_TYPE_OWNED_BY_REQUESTER = 3; //Equals 00000011
59 public const byte LAND_TYPE_PUBLIC = 0; //Equals 00000000 60 public const byte LAND_TYPE_IS_FOR_SALE = 4; //Equals 00000100
61 public const byte LAND_TYPE_IS_BEING_AUCTIONED = 5; //Equals 00000101
62 public const byte LAND_TYPE_unused6 = 6;
63 public const byte LAND_TYPE_unused7 = 7;
64 // next are flags
65 public const byte LAND_FLAG_unused8 = 0x08; // this may become excluside in future
66 public const byte LAND_FLAG_HIDEAVATARS = 0x10;
67 public const byte LAND_FLAG_LOCALSOUND = 0x20;
68 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = 0x40; //Equals 01000000
69 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = 0x80; //Equals 10000000
70
60 71
61 //These are other constants. Yay! 72 //These are other constants. Yay!
62 public const int START_LAND_LOCAL_ID = 1; 73 public const int START_LAND_LOCAL_ID = 1;
@@ -64,7 +75,7 @@ namespace OpenSim.Region.CoreModules.World.Land
64 #endregion 75 #endregion
65 76
66 private readonly Scene m_scene; 77 private readonly Scene m_scene;
67 private readonly LandManagementModule m_landManagementModule; 78 private readonly LandManagementModule m_landManagementModule;
68 79
69 public LandChannel(Scene scene, LandManagementModule landManagementMod) 80 public LandChannel(Scene scene, LandManagementModule landManagementMod)
70 { 81 {
@@ -80,7 +91,7 @@ namespace OpenSim.Region.CoreModules.World.Land
80 { 91 {
81 return m_landManagementModule.GetLandObject(x_float, y_float); 92 return m_landManagementModule.GetLandObject(x_float, y_float);
82 } 93 }
83 94
84 ILandObject obj = new LandObject(UUID.Zero, false, m_scene); 95 ILandObject obj = new LandObject(UUID.Zero, false, m_scene);
85 obj.LandData.Name = "NO LAND"; 96 obj.LandData.Name = "NO LAND";
86 return obj; 97 return obj;
@@ -95,6 +106,15 @@ namespace OpenSim.Region.CoreModules.World.Land
95 return null; 106 return null;
96 } 107 }
97 108
109 public ILandObject GetLandObject(UUID GlobalID)
110 {
111 if (m_landManagementModule != null)
112 {
113 return m_landManagementModule.GetLandObject(GlobalID);
114 }
115 return null;
116 }
117
98 public ILandObject GetLandObject(Vector3 position) 118 public ILandObject GetLandObject(Vector3 position)
99 { 119 {
100 return GetLandObject(position.X, position.Y); 120 return GetLandObject(position.X, position.Y);
@@ -106,7 +126,7 @@ namespace OpenSim.Region.CoreModules.World.Land
106 { 126 {
107 return m_landManagementModule.GetLandObject(x, y); 127 return m_landManagementModule.GetLandObject(x, y);
108 } 128 }
109 129
110 ILandObject obj = new LandObject(UUID.Zero, false, m_scene); 130 ILandObject obj = new LandObject(UUID.Zero, false, m_scene);
111 obj.LandData.Name = "NO LAND"; 131 obj.LandData.Name = "NO LAND";
112 return obj; 132 return obj;
@@ -121,7 +141,7 @@ namespace OpenSim.Region.CoreModules.World.Land
121 141
122 return new List<ILandObject>(); 142 return new List<ILandObject>();
123 } 143 }
124 144
125 public void Clear(bool setupDefaultParcel) 145 public void Clear(bool setupDefaultParcel)
126 { 146 {
127 if (m_landManagementModule != null) 147 if (m_landManagementModule != null)
@@ -156,6 +176,14 @@ namespace OpenSim.Region.CoreModules.World.Land
156 } 176 }
157 } 177 }
158 178
179 public void SendParcelsOverlay(IClientAPI client)
180 {
181 if (m_landManagementModule != null)
182 {
183 m_landManagementModule.SendParcelOverlay(client);
184 }
185 }
186
159 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) 187 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
160 { 188 {
161 if (m_landManagementModule != null) 189 if (m_landManagementModule != null)
@@ -171,7 +199,7 @@ namespace OpenSim.Region.CoreModules.World.Land
171 m_landManagementModule.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id); 199 m_landManagementModule.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
172 } 200 }
173 } 201 }
174 202
175 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 203 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
176 { 204 {
177 if (m_landManagementModule != null) 205 if (m_landManagementModule != null)
@@ -203,7 +231,13 @@ namespace OpenSim.Region.CoreModules.World.Land
203 m_landManagementModule.setParcelOtherCleanTime(remoteClient, localID, otherCleanTime); 231 m_landManagementModule.setParcelOtherCleanTime(remoteClient, localID, otherCleanTime);
204 } 232 }
205 } 233 }
206 234 public void sendClientInitialLandInfo(IClientAPI remoteClient)
235 {
236 if (m_landManagementModule != null)
237 {
238 m_landManagementModule.sendClientInitialLandInfo(remoteClient);
239 }
240 }
207 #endregion 241 #endregion
208 } 242 }
209} 243}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 92f6c1b..b1f5122 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -41,6 +41,7 @@ using OpenSim.Framework;
41using OpenSim.Framework.Capabilities; 41using OpenSim.Framework.Capabilities;
42using OpenSim.Framework.Console; 42using OpenSim.Framework.Console;
43using OpenSim.Framework.Servers; 43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Monitoring;
44using OpenSim.Framework.Servers.HttpServer; 45using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces; 46using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
@@ -52,7 +53,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
52namespace OpenSim.Region.CoreModules.World.Land 53namespace OpenSim.Region.CoreModules.World.Land
53{ 54{
54 // used for caching 55 // used for caching
55 internal class ExtendedLandData 56 internal class ExtendedLandData
56 { 57 {
57 public LandData LandData; 58 public LandData LandData;
58 public ulong RegionHandle; 59 public ulong RegionHandle;
@@ -69,9 +70,8 @@ namespace OpenSim.Region.CoreModules.World.Land
69 /// <summary> 70 /// <summary>
70 /// Minimum land unit size in region co-ordinates. 71 /// Minimum land unit size in region co-ordinates.
71 /// </summary> 72 /// </summary>
72 public const int LandUnit = 4;
73 73
74 private static readonly string remoteParcelRequestPath = "0009/"; 74 public const int LandUnit = 4;
75 75
76 private LandChannel landChannel; 76 private LandChannel landChannel;
77 private Scene m_scene; 77 private Scene m_scene;
@@ -89,20 +89,27 @@ namespace OpenSim.Region.CoreModules.World.Land
89 /// <value> 89 /// <value>
90 /// Land objects keyed by local id 90 /// Land objects keyed by local id
91 /// </value> 91 /// </value>
92 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); 92// private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
93
94 //ubit: removed the readonly so i can move it around
95 private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
96 private Dictionary<UUID, int> m_landUUIDList = new Dictionary<UUID, int>();
93 97
94 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 98 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
95 99
96 private bool m_allowedForcefulBans = true; 100 private bool m_allowedForcefulBans = true;
101 private bool m_showBansLines = true;
102 private UUID DefaultGodParcelGroup;
103 private string DefaultGodParcelName;
97 104
98 // caches ExtendedLandData 105 // caches ExtendedLandData
99 private Cache parcelInfoCache; 106 private Cache parcelInfoCache;
100 107
101
102 /// <summary> 108 /// <summary>
103 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. 109 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
104 /// </summary> 110 /// </summary>
105 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); 111 private HashSet<UUID> forcedPosition = new HashSet<UUID>();
112
106 113
107 // Enables limiting parcel layer info transmission when doing simple updates 114 // Enables limiting parcel layer info transmission when doing simple updates
108 private bool shouldLimitParcelLayerInfoToViewDistance { get; set; } 115 private bool shouldLimitParcelLayerInfoToViewDistance { get; set; }
@@ -125,6 +132,11 @@ namespace OpenSim.Region.CoreModules.World.Land
125 { 132 {
126 shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance); 133 shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance);
127 parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance); 134 parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance);
135 DefaultGodParcelGroup = new UUID(landManagementConfig.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
136 DefaultGodParcelName = landManagementConfig.GetString("DefaultAdministratorParcelName", "Default Parcel");
137 bool disablebans = landManagementConfig.GetBoolean("DisableParcelBans", !m_allowedForcefulBans);
138 m_allowedForcefulBans = !disablebans;
139 m_showBansLines = landManagementConfig.GetBoolean("ShowParcelBansLines", m_showBansLines);
128 } 140 }
129 } 141 }
130 142
@@ -132,17 +144,20 @@ namespace OpenSim.Region.CoreModules.World.Land
132 { 144 {
133 m_scene = scene; 145 m_scene = scene;
134 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; 146 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
147
135 landChannel = new LandChannel(scene, this); 148 landChannel = new LandChannel(scene, this);
136 149
137 parcelInfoCache = new Cache(); 150 parcelInfoCache = new Cache();
138 parcelInfoCache.Size = 30; // the number of different parcel requests in this region to cache 151 parcelInfoCache.Size = 30; // the number of different parcel requests in this region to cache
139 parcelInfoCache.DefaultTTL = new TimeSpan(0, 5, 0); 152 parcelInfoCache.DefaultTTL = new TimeSpan(0, 5, 0);
140 153
154 m_scene.EventManager.OnObjectAddedToScene += EventManagerOnParcelPrimCountAdd;
141 m_scene.EventManager.OnParcelPrimCountAdd += EventManagerOnParcelPrimCountAdd; 155 m_scene.EventManager.OnParcelPrimCountAdd += EventManagerOnParcelPrimCountAdd;
156
157 m_scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene;
142 m_scene.EventManager.OnParcelPrimCountUpdate += EventManagerOnParcelPrimCountUpdate; 158 m_scene.EventManager.OnParcelPrimCountUpdate += EventManagerOnParcelPrimCountUpdate;
143 m_scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene;
144 m_scene.EventManager.OnRequestParcelPrimCountUpdate += EventManagerOnRequestParcelPrimCountUpdate; 159 m_scene.EventManager.OnRequestParcelPrimCountUpdate += EventManagerOnRequestParcelPrimCountUpdate;
145 160
146 m_scene.EventManager.OnAvatarEnteringNewParcel += EventManagerOnAvatarEnteringNewParcel; 161 m_scene.EventManager.OnAvatarEnteringNewParcel += EventManagerOnAvatarEnteringNewParcel;
147 m_scene.EventManager.OnClientMovement += EventManagerOnClientMovement; 162 m_scene.EventManager.OnClientMovement += EventManagerOnClientMovement;
148 m_scene.EventManager.OnValidateLandBuy += EventManagerOnValidateLandBuy; 163 m_scene.EventManager.OnValidateLandBuy += EventManagerOnValidateLandBuy;
@@ -152,14 +167,14 @@ namespace OpenSim.Region.CoreModules.World.Land
152 m_scene.EventManager.OnSignificantClientMovement += EventManagerOnSignificantClientMovement; 167 m_scene.EventManager.OnSignificantClientMovement += EventManagerOnSignificantClientMovement;
153 m_scene.EventManager.OnNoticeNoLandDataFromStorage += EventManagerOnNoLandDataFromStorage; 168 m_scene.EventManager.OnNoticeNoLandDataFromStorage += EventManagerOnNoLandDataFromStorage;
154 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; 169 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage;
155 m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan; 170 m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan;
156 m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps; 171 m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps;
157 172
158 lock (m_scene) 173 lock (m_scene)
159 { 174 {
160 m_scene.LandChannel = (ILandChannel)landChannel; 175 m_scene.LandChannel = (ILandChannel)landChannel;
161 } 176 }
162 177
163 RegisterCommands(); 178 RegisterCommands();
164 } 179 }
165 180
@@ -172,8 +187,8 @@ namespace OpenSim.Region.CoreModules.World.Land
172 } 187 }
173 188
174 public void RemoveRegion(Scene scene) 189 public void RemoveRegion(Scene scene)
175 { 190 {
176 // TODO: Release event manager listeners here 191 // TODO: Release event manager listeners here
177 } 192 }
178 193
179// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason) 194// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
@@ -181,7 +196,7 @@ namespace OpenSim.Region.CoreModules.World.Land
181// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y); 196// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
182// reason = "You are not allowed to enter this sim."; 197// reason = "You are not allowed to enter this sim.";
183// return nearestParcel != null; 198// return nearestParcel != null;
184// } 199// }
185 200
186 void EventManagerOnNewClient(IClientAPI client) 201 void EventManagerOnNewClient(IClientAPI client)
187 { 202 {
@@ -199,18 +214,10 @@ namespace OpenSim.Region.CoreModules.World.Land
199 client.OnParcelReclaim += ClientOnParcelReclaim; 214 client.OnParcelReclaim += ClientOnParcelReclaim;
200 client.OnParcelInfoRequest += ClientOnParcelInfoRequest; 215 client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
201 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; 216 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
202 client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
203 client.OnParcelEjectUser += ClientOnParcelEjectUser; 217 client.OnParcelEjectUser += ClientOnParcelEjectUser;
204 client.OnParcelFreezeUser += ClientOnParcelFreezeUser; 218 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
205 client.OnSetStartLocationRequest += ClientOnSetHome; 219 client.OnSetStartLocationRequest += ClientOnSetHome;
206 220 client.OnParcelBuyPass += ClientParcelBuyPass;
207
208 EntityBase presenceEntity;
209 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
210 {
211 SendLandUpdate((ScenePresence)presenceEntity, true);
212 SendParcelOverlay(client);
213 }
214 } 221 }
215 222
216 public void EventMakeChildAgent(ScenePresence avatar) 223 public void EventMakeChildAgent(ScenePresence avatar)
@@ -218,52 +225,6 @@ namespace OpenSim.Region.CoreModules.World.Land
218 avatar.currentParcelUUID = UUID.Zero; 225 avatar.currentParcelUUID = UUID.Zero;
219 } 226 }
220 227
221 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
222 {
223 //If we are forcing a position for them to go
224 if (forcedPosition.ContainsKey(remoteClient.AgentId))
225 {
226 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
227
228 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
229 //When the avatar walks into a ban line on the ground, it prevents getting stuck
230 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
231
232 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
233 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
234 {
235// m_log.DebugFormat(
236// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
237// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
238
239 forcedPosition.Remove(remoteClient.AgentId);
240 }
241 //if we are far away, teleport
242 else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
243 {
244 Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
245// m_log.DebugFormat(
246// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
247// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
248
249 m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
250 forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
251
252 forcedPosition.Remove(remoteClient.AgentId);
253 }
254 else
255 {
256// m_log.DebugFormat(
257// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
258// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
259
260 //Forces them toward the forced position we want if they aren't there yet
261 agentData.UseClientAgentPosition = true;
262 agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
263 }
264 }
265 }
266
267 public void Close() 228 public void Close()
268 { 229 {
269 } 230 }
@@ -291,7 +252,10 @@ namespace OpenSim.Region.CoreModules.World.Land
291 lock (m_landList) 252 lock (m_landList)
292 { 253 {
293 if (m_landList.TryGetValue(local_id, out land)) 254 if (m_landList.TryGetValue(local_id, out land))
255 {
294 land.LandData = newData; 256 land.LandData = newData;
257 m_landUUIDList[newData.GlobalID] = local_id;
258 }
295 } 259 }
296 260
297 if (land != null) 261 if (land != null)
@@ -312,28 +276,35 @@ namespace OpenSim.Region.CoreModules.World.Land
312 //Remove all the land objects in the sim and add a blank, full sim land object set to public 276 //Remove all the land objects in the sim and add a blank, full sim land object set to public
313 lock (m_landList) 277 lock (m_landList)
314 { 278 {
279 foreach(ILandObject parcel in m_landList.Values)
280 parcel.Clear();
281
315 m_landList.Clear(); 282 m_landList.Clear();
283 m_landUUIDList.Clear();
316 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 284 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
285
317 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; 286 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
318 } 287 }
319 } 288 }
320 289
321 /// <summary> 290 /// <summary>
322 /// Create a default parcel that spans the entire region and is owned by the estate owner. 291 /// Create a default parcel that spans the entire region and is owned by the estate owner.
323 /// </summary> 292 /// </summary>
324 /// <returns>The parcel created.</returns> 293 /// <returns>The parcel created.</returns>
325 protected ILandObject CreateDefaultParcel() 294 protected ILandObject CreateDefaultParcel()
326 { 295 {
327 m_log.DebugFormat( 296 m_log.DebugFormat("{0} Creating default parcel for region {1}", LogHeader, m_scene.RegionInfo.RegionName);
328 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 297
329 298 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
330 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 299
331 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, 300 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
332 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY)); 301 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
333 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 302 LandData ldata = fullSimParcel.LandData;
334 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 303 ldata.SimwideArea = ldata.Area;
335 304 ldata.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
336 return AddLandObject(fullSimParcel); 305 ldata.ClaimDate = Util.UnixTimeSinceEpoch();
306
307 return AddLandObject(fullSimParcel);
337 } 308 }
338 309
339 public List<ILandObject> AllParcels() 310 public List<ILandObject> AllParcels()
@@ -347,9 +318,9 @@ namespace OpenSim.Region.CoreModules.World.Land
347 public List<ILandObject> ParcelsNearPoint(Vector3 position) 318 public List<ILandObject> ParcelsNearPoint(Vector3 position)
348 { 319 {
349 List<ILandObject> parcelsNear = new List<ILandObject>(); 320 List<ILandObject> parcelsNear = new List<ILandObject>();
350 for (int x = -4; x <= 4; x += 4) 321 for (int x = -8; x <= 8; x += 4)
351 { 322 {
352 for (int y = -4; y <= 4; y += 4) 323 for (int y = -8; y <= 8; y += 4)
353 { 324 {
354 ILandObject check = GetLandObject(position.X + x, position.Y + y); 325 ILandObject check = GetLandObject(position.X + x, position.Y + y);
355 if (check != null) 326 if (check != null)
@@ -365,33 +336,99 @@ namespace OpenSim.Region.CoreModules.World.Land
365 return parcelsNear; 336 return parcelsNear;
366 } 337 }
367 338
368 public void SendYouAreBannedNotice(ScenePresence avatar) 339 // checks and enforces bans or restrictions
340 // returns true if enforced
341 public bool EnforceBans(ILandObject land, ScenePresence avatar)
369 { 342 {
370 if (AllowedForcefulBans) 343 Vector3 agentpos = avatar.AbsolutePosition;
344 float h = m_scene.GetGroundHeight(agentpos.X, agentpos.Y) + LandChannel.BAN_LINE_SAFETY_HEIGHT;
345 float zdif = avatar.AbsolutePosition.Z - h;
346 if (zdif > 0 )
347 {
348 forcedPosition.Remove(avatar.UUID);
349 avatar.lastKnownAllowedPosition = agentpos;
350 return false;
351 }
352
353 bool ban = false;
354 string reason = "";
355 if (land.IsRestrictedFromLand(avatar.UUID))
371 { 356 {
372 avatar.ControllingClient.SendAlertMessage( 357 reason = "You do not have access to the parcel";
373 "You are not allowed on this parcel because you are banned. Please go away."); 358 ban = true;
359 }
360
361 if (land.IsBannedFromLand(avatar.UUID))
362 {
363 if ( m_allowedForcefulBans)
364 {
365 reason ="You are banned from parcel";
366 ban = true;
367 }
368 else if(!ban)
369 {
370 if (forcedPosition.Contains(avatar.UUID))
371 avatar.ControllingClient.SendAlertMessage("You are banned from parcel, please leave by your own will");
372 forcedPosition.Remove(avatar.UUID);
373 avatar.lastKnownAllowedPosition = agentpos;
374 return false;
375 }
376 }
377
378 if(ban)
379 {
380 if (!forcedPosition.Contains(avatar.UUID))
381 avatar.ControllingClient.SendAlertMessage(reason);
382
383 if(zdif > -4f)
384 {
385
386 agentpos.Z = h + 4.0f;
387 ForceAvatarToPosition(avatar, agentpos);
388 return true;
389 }
390
391 if (land.ContainsPoint((int)avatar.lastKnownAllowedPosition.X,
392 (int) avatar.lastKnownAllowedPosition.Y))
393 {
394 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
395 if (pos == null)
396 {
397 forcedPosition.Remove(avatar.UUID);
398 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
399 }
400 else
401 ForceAvatarToPosition(avatar, (Vector3)pos);
402 }
403 else
404 {
405 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
406 }
407 return true;
374 } 408 }
375 else 409 else
376 { 410 {
377 avatar.ControllingClient.SendAlertMessage( 411 forcedPosition.Remove(avatar.UUID);
378 "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim!"); 412 avatar.lastKnownAllowedPosition = agentpos;
413 return false;
379 } 414 }
380 } 415 }
381 416
382 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 417 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
383 { 418 {
384 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 419 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
385 if (position.HasValue)
386 {
387 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position;
388 }
389 }
390 420
391 public void SendYouAreRestrictedNotice(ScenePresence avatar) 421 if (!position.HasValue)
392 { 422 return;
393 avatar.ControllingClient.SendAlertMessage( 423
394 "You are not allowed on this parcel because the land owner has restricted access."); 424 if(avatar.MovingToTarget)
425 avatar.ResetMoveToTarget();
426 avatar.AbsolutePosition = position.Value;
427 avatar.lastKnownAllowedPosition = position.Value;
428 avatar.Velocity = Vector3.Zero;
429 if(avatar.IsSatOnObject)
430 avatar.StandUp();
431 forcedPosition.Add(avatar.UUID);
395 } 432 }
396 433
397 public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID) 434 public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
@@ -404,29 +441,12 @@ namespace OpenSim.Region.CoreModules.World.Land
404 parcelAvatarIsEntering = m_landList[localLandID]; 441 parcelAvatarIsEntering = m_landList[localLandID];
405 } 442 }
406 443
407 if (parcelAvatarIsEntering != null) 444 if (parcelAvatarIsEntering != null &&
445 avatar.currentParcelUUID != parcelAvatarIsEntering.LandData.GlobalID)
408 { 446 {
409 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) 447 SendLandUpdate(avatar, parcelAvatarIsEntering);
410 { 448 avatar.currentParcelUUID = parcelAvatarIsEntering.LandData.GlobalID;
411 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) 449 EnforceBans(parcelAvatarIsEntering, avatar);
412 {
413 SendYouAreBannedNotice(avatar);
414 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
415 }
416 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
417 {
418 SendYouAreRestrictedNotice(avatar);
419 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
420 }
421 else
422 {
423 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
424 }
425 }
426 else
427 {
428 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
429 }
430 } 450 }
431 } 451 }
432 } 452 }
@@ -434,7 +454,7 @@ namespace OpenSim.Region.CoreModules.World.Land
434 public void SendOutNearestBanLine(IClientAPI client) 454 public void SendOutNearestBanLine(IClientAPI client)
435 { 455 {
436 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 456 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
437 if (sp == null || sp.IsChildAgent) 457 if (sp == null || sp.IsDeleted)
438 return; 458 return;
439 459
440 List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition); 460 List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition);
@@ -454,98 +474,180 @@ namespace OpenSim.Region.CoreModules.World.Land
454 return; 474 return;
455 } 475 }
456 476
457 public void SendLandUpdate(ScenePresence avatar, bool force) 477 public void sendClientInitialLandInfo(IClientAPI remoteClient)
458 { 478 {
459 ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 479 ScenePresence avatar;
460 (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
461 480
462 if (over != null) 481 if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out avatar))
482 return;
483
484 if (!avatar.IsChildAgent)
463 { 485 {
464 if (force) 486 ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
465 { 487 if (over == null)
466 if (!avatar.IsChildAgent) 488 return;
467 {
468 over.SendLandUpdateToClient(avatar.ControllingClient);
469 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
470 m_scene.RegionInfo.RegionID);
471 }
472 }
473 489
474 if (avatar.currentParcelUUID != over.LandData.GlobalID) 490 avatar.currentParcelUUID = over.LandData.GlobalID;
475 { 491 over.SendLandUpdateToClient(avatar.ControllingClient);
476 if (!avatar.IsChildAgent)
477 {
478 over.SendLandUpdateToClient(avatar.ControllingClient);
479 avatar.currentParcelUUID = over.LandData.GlobalID;
480 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
481 m_scene.RegionInfo.RegionID);
482 }
483 }
484 } 492 }
493 SendParcelOverlay(remoteClient);
485 } 494 }
486 495
487 public void SendLandUpdate(ScenePresence avatar) 496 public void SendLandUpdate(ScenePresence avatar, ILandObject over)
488 { 497 {
489 SendLandUpdate(avatar, false); 498 if (avatar.IsChildAgent)
490 } 499 return;
491 500
492 public void EventManagerOnSignificantClientMovement(ScenePresence clientAvatar) 501 if (over != null)
493 {
494 SendLandUpdate(clientAvatar);
495 SendOutNearestBanLine(clientAvatar.ControllingClient);
496 ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
497 if (parcel != null)
498 { 502 {
499 if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && 503 over.SendLandUpdateToClient(avatar.ControllingClient);
500 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) 504// sl doesnt seem to send this now, as it used 2
501 { 505// SendParcelOverlay(avatar.ControllingClient);
502 EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID,
503 m_scene.RegionInfo.RegionID);
504 //They are going under the safety line!
505 if (!parcel.IsBannedFromLand(clientAvatar.UUID))
506 {
507 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
508 }
509 }
510 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
511 parcel.IsBannedFromLand(clientAvatar.UUID))
512 {
513 //once we've sent the message once, keep going toward the target until we are done
514 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
515 {
516 SendYouAreBannedNotice(clientAvatar);
517 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
518 }
519 }
520 else if (parcel.IsRestrictedFromLand(clientAvatar.UUID))
521 {
522 //once we've sent the message once, keep going toward the target until we are done
523 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
524 {
525 SendYouAreRestrictedNotice(clientAvatar);
526 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
527 }
528 }
529 else
530 {
531 //when we are finally in a safe place, lets release the forced position lock
532 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
533 }
534 } 506 }
535 } 507 }
536 508
509 public void EventManagerOnSignificantClientMovement(ScenePresence avatar)
510 {
511 if (avatar.IsChildAgent)
512 return;
513
514 if ( m_allowedForcefulBans && m_showBansLines)
515 SendOutNearestBanLine(avatar.ControllingClient);
516 }
517
537 /// <summary> 518 /// <summary>
538 /// Like handleEventManagerOnSignificantClientMovement, but called with an AgentUpdate regardless of distance. 519 /// Like handleEventManagerOnSignificantClientMovement, but called with an AgentUpdate regardless of distance.
539 /// </summary> 520 /// </summary>
540 /// <param name="avatar"></param> 521 /// <param name="avatar"></param>
541 public void EventManagerOnClientMovement(ScenePresence avatar) 522 public void EventManagerOnClientMovement(ScenePresence avatar)
542 { 523 {
524 if (avatar.IsChildAgent)
525 return;
526
543 Vector3 pos = avatar.AbsolutePosition; 527 Vector3 pos = avatar.AbsolutePosition;
544 ILandObject over = GetLandObject(pos.X, pos.Y); 528 ILandObject over = GetLandObject(pos.X, pos.Y);
545 if (over != null) 529 if (over != null)
546 { 530 {
547 if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || pos.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT)) 531 EnforceBans(over, avatar);
548 avatar.lastKnownAllowedPosition = pos; 532 pos = avatar.AbsolutePosition;
533 ILandObject newover = GetLandObject(pos.X, pos.Y);
534 if(over != newover || avatar.currentParcelUUID != newover.LandData.GlobalID)
535 {
536 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar,
537 newover.LandData.LocalID, m_scene.RegionInfo.RegionID);
538 }
539 }
540 }
541
542 public void ClientParcelBuyPass(IClientAPI remote_client, UUID targetID, int landLocalID)
543 {
544 ILandObject land;
545 lock (m_landList)
546 {
547 m_landList.TryGetValue(landLocalID, out land);
548 }
549 // trivial checks
550 if(land == null)
551 return;
552
553 LandData ldata = land.LandData;
554
555 if(ldata == null)
556 return;
557
558 if(ldata.OwnerID == targetID)
559 return;
560
561 if(ldata.PassHours == 0)
562 return;
563
564 // don't allow passes on group owned until we can give money to groups
565 if(ldata.IsGroupOwned)
566 {
567 remote_client.SendAgentAlertMessage("pass to group owned parcel not suported", false);
568 return;
569 }
570
571 if((ldata.Flags & (uint)ParcelFlags.UsePassList) == 0)
572 return;
573
574 int cost = ldata.PassPrice;
575
576 int idx = land.LandData.ParcelAccessList.FindIndex(
577 delegate(LandAccessEntry e)
578 {
579 if (e.AgentID == targetID && e.Flags == AccessList.Access)
580 return true;
581 return false;
582 });
583 int now = Util.UnixTimeSinceEpoch();
584 int expires = (int)(3600.0 * ldata.PassHours + 0.5f);
585 int currenttime = -1;
586 if (idx != -1)
587 {
588 if(ldata.ParcelAccessList[idx].Expires == 0)
589 {
590 remote_client.SendAgentAlertMessage("You already have access to parcel", false);
591 return;
592 }
593
594 currenttime = ldata.ParcelAccessList[idx].Expires - now;
595 if(currenttime > (int)(0.25f * expires + 0.5f))
596 {
597 if(currenttime > 3600)
598 remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.###} hours",
599 currenttime/3600f), false);
600 else if(currenttime > 60)
601 remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.##} minutes",
602 currenttime/60f), false);
603 else
604 remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.#} seconds",
605 currenttime), false);
606 return;
607 }
608 }
609
610 LandAccessEntry entry = new LandAccessEntry();
611 entry.AgentID = targetID;
612 entry.Flags = AccessList.Access;
613 entry.Expires = now + expires;
614 if(currenttime > 0)
615 entry.Expires += currenttime;
616 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
617 if(cost != 0 && mm != null)
618 {
619 WorkManager.RunInThreadPool(
620 delegate
621 {
622 string regionName = m_scene.RegionInfo.RegionName;
623
624 if (!mm.AmountCovered(remote_client.AgentId, cost))
625 {
626 remote_client.SendAgentAlertMessage(String.Format("Insufficient funds in region '{0}' money system", regionName), true);
627 return;
628 }
629
630 string payDescription = String.Format("Parcel '{0}' at region '{1} {2:0.###} hours access pass", ldata.Name, regionName, ldata.PassHours);
631
632 if(!mm.MoveMoney(remote_client.AgentId, ldata.OwnerID, cost,MoneyTransactionType.LandPassSale, payDescription))
633 {
634 remote_client.SendAgentAlertMessage("Sorry pass payment processing failed, please try again later", true);
635 return;
636 }
637
638 if (idx != -1)
639 ldata.ParcelAccessList.RemoveAt(idx);
640 ldata.ParcelAccessList.Add(entry);
641 m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
642 return;
643 }, null, "ParcelBuyPass");
644 }
645 else
646 {
647 if (idx != -1)
648 ldata.ParcelAccessList.RemoveAt(idx);
649 ldata.ParcelAccessList.Add(entry);
650 m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
549 } 651 }
550 } 652 }
551 653
@@ -589,7 +691,7 @@ namespace OpenSim.Region.CoreModules.World.Land
589 requiredPowers = GroupPowers.LandManageBanned; 691 requiredPowers = GroupPowers.LandManageBanned;
590 692
591 if (m_scene.Permissions.CanEditParcelProperties(agentID, 693 if (m_scene.Permissions.CanEditParcelProperties(agentID,
592 land, requiredPowers)) 694 land, requiredPowers, false))
593 { 695 {
594 land.UpdateAccessList(flags, transactionID, sequenceID, 696 land.UpdateAccessList(flags, transactionID, sequenceID,
595 sections, entries, remote_client); 697 sections, entries, remote_client);
@@ -605,13 +707,11 @@ namespace OpenSim.Region.CoreModules.World.Land
605 /// Adds a land object to the stored list and adds them to the landIDList to what they own 707 /// Adds a land object to the stored list and adds them to the landIDList to what they own
606 /// </summary> 708 /// </summary>
607 /// <param name="new_land"> 709 /// <param name="new_land">
608 /// The land object being added. 710 /// The land object being added.
609 /// Will return null if this overlaps with an existing parcel that has not had its bitmap adjusted. 711 /// Will return null if this overlaps with an existing parcel that has not had its bitmap adjusted.
610 /// </param> 712 /// </param>
611 public ILandObject AddLandObject(ILandObject land) 713 public ILandObject AddLandObject(ILandObject new_land)
612 { 714 {
613 ILandObject new_land = land.Copy();
614
615 // Only now can we add the prim counts to the land object - we rely on the global ID which is generated 715 // Only now can we add the prim counts to the land object - we rely on the global ID which is generated
616 // as a random UUID inside LandData initialization 716 // as a random UUID inside LandData initialization
617 if (m_primCountModule != null) 717 if (m_primCountModule != null)
@@ -623,18 +723,15 @@ namespace OpenSim.Region.CoreModules.World.Land
623 new_land.LandData.LocalID = newLandLocalID; 723 new_land.LandData.LocalID = newLandLocalID;
624 724
625 bool[,] landBitmap = new_land.GetLandBitmap(); 725 bool[,] landBitmap = new_land.GetLandBitmap();
626 // m_log.DebugFormat("{0} AddLandObject. new_land.bitmapSize=({1},{2}). newLocalID={3}",
627 // LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), newLandLocalID);
628
629 if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1)) 726 if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
630 { 727 {
631 // Going to variable sized regions can cause mismatches 728 // Going to variable sized regions can cause mismatches
632 m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})", 729 m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})",
633 LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1) ); 730 LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1));
634 } 731 }
635 else 732 else
636 { 733 {
637 // If other land objects still believe that they occupy any parts of the same space, 734 // If other land objects still believe that they occupy any parts of the same space,
638 // then do not allow the add to proceed. 735 // then do not allow the add to proceed.
639 for (int x = 0; x < landBitmap.GetLength(0); x++) 736 for (int x = 0; x < landBitmap.GetLength(0); x++)
640 { 737 {
@@ -652,7 +749,7 @@ namespace OpenSim.Region.CoreModules.World.Land
652 { 749 {
653 m_log.ErrorFormat( 750 m_log.ErrorFormat(
654 "{0}: Cannot add parcel \"{1}\", local ID {2} at tile {3},{4} because this is still occupied by parcel \"{5}\", local ID {6} in {7}", 751 "{0}: Cannot add parcel \"{1}\", local ID {2} at tile {3},{4} because this is still occupied by parcel \"{5}\", local ID {6} in {7}",
655 LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y, 752 LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y,
656 lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name); 753 lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name);
657 754
658 return null; 755 return null;
@@ -668,10 +765,10 @@ namespace OpenSim.Region.CoreModules.World.Land
668 { 765 {
669 if (landBitmap[x, y]) 766 if (landBitmap[x, y])
670 { 767 {
671 // m_log.DebugFormat( 768 // m_log.DebugFormat(
672 // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", 769 // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
673 // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName); 770 // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
674 771
675 m_landIDList[x, y] = newLandLocalID; 772 m_landIDList[x, y] = newLandLocalID;
676 } 773 }
677 } 774 }
@@ -679,6 +776,7 @@ namespace OpenSim.Region.CoreModules.World.Land
679 } 776 }
680 777
681 m_landList.Add(newLandLocalID, new_land); 778 m_landList.Add(newLandLocalID, new_land);
779 m_landUUIDList[new_land.LandData.GlobalID] = newLandLocalID;
682 m_lastLandLocalID++; 780 m_lastLandLocalID++;
683 } 781 }
684 782
@@ -695,6 +793,7 @@ namespace OpenSim.Region.CoreModules.World.Land
695 public void removeLandObject(int local_id) 793 public void removeLandObject(int local_id)
696 { 794 {
697 ILandObject land; 795 ILandObject land;
796 UUID landGlobalID = UUID.Zero;
698 lock (m_landList) 797 lock (m_landList)
699 { 798 {
700 for (int x = 0; x < m_landIDList.GetLength(0); x++) 799 for (int x = 0; x < m_landIDList.GetLength(0); x++)
@@ -713,37 +812,47 @@ namespace OpenSim.Region.CoreModules.World.Land
713 812
714 land = m_landList[local_id]; 813 land = m_landList[local_id];
715 m_landList.Remove(local_id); 814 m_landList.Remove(local_id);
815 if(land != null && land.LandData != null)
816 {
817 landGlobalID = land.LandData.GlobalID;
818 m_landUUIDList.Remove(landGlobalID);
819 }
716 } 820 }
717 821
718 m_scene.EventManager.TriggerLandObjectRemoved(land.LandData.GlobalID); 822 if(landGlobalID != UUID.Zero)
823 {
824 m_scene.EventManager.TriggerLandObjectRemoved(landGlobalID);
825 land.Clear();
826 }
719 } 827 }
720 828
721 /// <summary> 829 /// <summary>
722 /// Clear the scene of all parcels 830 /// Clear the scene of all parcels
723 /// </summary> 831 /// </summary>
724 public void Clear(bool setupDefaultParcel) 832 public void Clear(bool setupDefaultParcel)
725 { 833 {
726 List<ILandObject> parcels; 834 Dictionary<int, ILandObject> landworkList;
835 // move to work pointer since we are deleting it all
727 lock (m_landList) 836 lock (m_landList)
728 { 837 {
729 parcels = new List<ILandObject>(m_landList.Values); 838 landworkList = m_landList;
839 m_landList = new Dictionary<int, ILandObject>();
730 } 840 }
731 841
732 foreach (ILandObject lo in parcels) 842 // this 2 methods have locks (now)
843 ResetSimLandObjects();
844
845 if (setupDefaultParcel)
846 CreateDefaultParcel();
847
848 // fire outside events unlocked
849 foreach (ILandObject lo in landworkList.Values)
733 { 850 {
734 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 851 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
735 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); 852 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
736 } 853 }
854 landworkList.Clear();
737 855
738 lock (m_landList)
739 {
740 m_landList.Clear();
741
742 ResetSimLandObjects();
743 }
744
745 if (setupDefaultParcel)
746 CreateDefaultParcel();
747 } 856 }
748 857
749 private void performFinalLandJoin(ILandObject master, ILandObject slave) 858 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -762,11 +871,29 @@ namespace OpenSim.Region.CoreModules.World.Land
762 } 871 }
763 } 872 }
764 } 873 }
765 874 master.LandData.Dwell += slave.LandData.Dwell;
766 removeLandObject(slave.LandData.LocalID); 875 removeLandObject(slave.LandData.LocalID);
767 UpdateLandObject(master.LandData.LocalID, master.LandData); 876 UpdateLandObject(master.LandData.LocalID, master.LandData);
768 } 877 }
769 878
879 public ILandObject GetLandObject(UUID globalID)
880 {
881 lock (m_landList)
882 {
883 int lid = -1;
884 if(m_landUUIDList.TryGetValue(globalID, out lid) && lid >= 0)
885 {
886 if (m_landList.ContainsKey(lid))
887 {
888 return m_landList[lid];
889 }
890 else
891 m_landUUIDList.Remove(globalID); // auto heal
892 }
893 }
894 return null;
895 }
896
770 public ILandObject GetLandObject(int parcelLocalID) 897 public ILandObject GetLandObject(int parcelLocalID)
771 { 898 {
772 lock (m_landList) 899 lock (m_landList)
@@ -787,58 +914,37 @@ namespace OpenSim.Region.CoreModules.World.Land
787 /// <returns>Land object at the point supplied</returns> 914 /// <returns>Land object at the point supplied</returns>
788 public ILandObject GetLandObject(float x_float, float y_float) 915 public ILandObject GetLandObject(float x_float, float y_float)
789 { 916 {
790 return GetLandObject((int)x_float, (int)y_float, true /* returnNullIfLandObjectNotFound */); 917 return GetLandObject((int)x_float, (int)y_float, true);
791 /* 918 }
792 int x;
793 int y;
794
795 if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0)
796 return null;
797 919
798 try 920 // if x,y is off region this will return the parcel at cliped x,y
799 { 921 // as did code it replaces
800 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit)); 922 public ILandObject GetLandObjectClipedXY(float x, float y)
801 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit)); 923 {
802 } 924 //do clip inline
803 catch (OverflowException) 925 int avx = (int)x;
804 { 926 if (avx < 0)
805 return null; 927 avx = 0;
806 } 928 else if (avx >= m_scene.RegionInfo.RegionSizeX)
929 avx = (int)Constants.RegionSize - 1;
807 930
808 if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit) 931 int avy = (int)y;
809 || y >= (m_scene.RegionInfo.RegionSizeY / landUnit) 932 if (avy < 0)
810 || x < 0 933 avy = 0;
811 || y < 0) 934 else if (avy >= m_scene.RegionInfo.RegionSizeY)
812 { 935 avy = (int)Constants.RegionSize - 1;
813 return null;
814 }
815 936
816 lock (m_landList) 937 lock (m_landIDList)
817 { 938 {
818 // Corner case. If an autoreturn happens during sim startup
819 // we will come here with the list uninitialized
820 //
821// int landId = m_landIDList[x, y];
822
823// if (landId == 0)
824// m_log.DebugFormat(
825// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
826// x, y, m_scene.RegionInfo.RegionName);
827
828 try 939 try
829 { 940 {
830 if (m_landList.ContainsKey(m_landIDList[x, y])) 941 return m_landList[m_landIDList[avx / LandUnit, avy / LandUnit]];
831 return m_landList[m_landIDList[x, y]];
832 } 942 }
833 catch (Exception e) 943 catch (IndexOutOfRangeException)
834 { 944 {
835 m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})", 945 return null;
836 LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
837 } 946 }
838
839 return null;
840 } 947 }
841 */
842 } 948 }
843 949
844 // Public entry. 950 // Public entry.
@@ -848,33 +954,32 @@ namespace OpenSim.Region.CoreModules.World.Land
848 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */); 954 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */);
849 } 955 }
850 956
851 /// <summary> 957 public ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds)
852 /// Given a region position, return the parcel land object for that location
853 /// </summary>
854 /// <returns>
855 /// The land object.
856 /// </returns>
857 /// <param name='x'></param>
858 /// <param name='y'></param>
859 /// <param name='returnNullIfLandObjectNotFound'>
860 /// Return null if the land object requested is not within the region's bounds.
861 /// </param>
862 private ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds)
863 { 958 {
864 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0) 959 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
865 { 960 {
866 // These exceptions here will cause a lot of complaints from the users specifically because 961 // These exceptions here will cause a lot of complaints from the users specifically because
867 // they happen every time at border crossings 962 // they happen every time at border crossings
868 if (returnNullIfLandObjectOutsideBounds) 963 if (returnNullIfLandObjectOutsideBounds)
869 return null; 964 return null;
870 else 965 else
871 throw new Exception( 966 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
872 String.Format("{0} GetLandObject for non-existent position. Region={1}, pos=<{2},{3}",
873 LogHeader, m_scene.RegionInfo.RegionName, x, y)
874 );
875 } 967 }
876 968
877 return m_landList[m_landIDList[x / 4, y / 4]]; 969 if(m_landList.Count == 0 || m_landIDList == null)
970 return null;
971
972 lock (m_landIDList)
973 {
974 try
975 {
976 return m_landList[m_landIDList[x / 4, y / 4]];
977 }
978 catch (IndexOutOfRangeException)
979 {
980 return null;
981 }
982 }
878 } 983 }
879 984
880 // Create a 'parcel is here' bitmap for the parcel identified by the passed landID 985 // Create a 'parcel is here' bitmap for the parcel identified by the passed landID
@@ -926,7 +1031,7 @@ namespace OpenSim.Region.CoreModules.World.Land
926 } 1031 }
927 } 1032 }
928 1033
929 public void FinalizeLandPrimCountUpdate() 1034 private void FinalizeLandPrimCountUpdate()
930 { 1035 {
931 //Get Simwide prim count for owner 1036 //Get Simwide prim count for owner
932 Dictionary<UUID, List<LandObject>> landOwnersAndParcels = new Dictionary<UUID, List<LandObject>>(); 1037 Dictionary<UUID, List<LandObject>> landOwnersAndParcels = new Dictionary<UUID, List<LandObject>>();
@@ -967,10 +1072,10 @@ namespace OpenSim.Region.CoreModules.World.Land
967 1072
968 public void EventManagerOnParcelPrimCountUpdate() 1073 public void EventManagerOnParcelPrimCountUpdate()
969 { 1074 {
970// m_log.DebugFormat( 1075 //m_log.DebugFormat(
971// "[LAND MANAGEMENT MODULE]: Triggered EventManagerOnParcelPrimCountUpdate() for {0}", 1076 // "[land management module]: triggered eventmanageronparcelprimcountupdate() for {0}",
972// m_scene.RegionInfo.RegionName); 1077 // m_scene.RegionInfo.RegionName);
973 1078
974 ResetOverMeRecords(); 1079 ResetOverMeRecords();
975 EntityBase[] entities = m_scene.Entities.GetEntities(); 1080 EntityBase[] entities = m_scene.Entities.GetEntities();
976 foreach (EntityBase obj in entities) 1081 foreach (EntityBase obj in entities)
@@ -1002,27 +1107,33 @@ namespace OpenSim.Region.CoreModules.World.Land
1002 /// <param name="end_y">North Point</param> 1107 /// <param name="end_y">North Point</param>
1003 /// <param name="attempting_user_id">UUID of user who is trying to subdivide</param> 1108 /// <param name="attempting_user_id">UUID of user who is trying to subdivide</param>
1004 /// <returns>Returns true if successful</returns> 1109 /// <returns>Returns true if successful</returns>
1005 private void subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) 1110 public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
1006 { 1111 {
1007 //First, lets loop through the points and make sure they are all in the same peice of land 1112 //First, lets loop through the points and make sure they are all in the same peice of land
1008 //Get the land object at start 1113 //Get the land object at start
1009 1114
1010 ILandObject startLandObject = GetLandObject(start_x, start_y); 1115 ILandObject startLandObject = GetLandObject(start_x, start_y);
1011 1116
1012 if (startLandObject == null) return; 1117 if (startLandObject == null)
1118 return;
1119
1120 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin, true))
1121 {
1122 return;
1123 }
1013 1124
1014 //Loop through the points 1125 //Loop through the points
1015 try 1126 try
1016 { 1127 {
1017 int totalX = end_x - start_x; 1128 for (int y = start_y; y < end_y; y++)
1018 int totalY = end_y - start_y;
1019 for (int y = 0; y < totalY; y++)
1020 { 1129 {
1021 for (int x = 0; x < totalX; x++) 1130 for (int x = start_x; x < end_x; x++)
1022 { 1131 {
1023 ILandObject tempLandObject = GetLandObject(start_x + x, start_y + y); 1132 ILandObject tempLandObject = GetLandObject(x, y);
1024 if (tempLandObject == null) return; 1133 if (tempLandObject == null)
1025 if (tempLandObject != startLandObject) return; 1134 return;
1135 if (tempLandObject != startLandObject)
1136 return;
1026 } 1137 }
1027 } 1138 }
1028 } 1139 }
@@ -1031,22 +1142,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1031 return; 1142 return;
1032 } 1143 }
1033 1144
1034 //If we are still here, then they are subdividing within one piece of land 1145 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
1035 //Check owner
1036 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin))
1037 {
1038 return;
1039 }
1040
1041 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
1042 ILandObject newLand = startLandObject.Copy(); 1146 ILandObject newLand = startLandObject.Copy();
1147
1043 newLand.LandData.Name = newLand.LandData.Name; 1148 newLand.LandData.Name = newLand.LandData.Name;
1044 newLand.LandData.GlobalID = UUID.Random(); 1149 newLand.LandData.GlobalID = UUID.Random();
1045 newLand.LandData.Dwell = 0; 1150 newLand.LandData.Dwell = 0;
1151 // Clear "Show in search" on the cut out parcel to prevent double-charging
1152 newLand.LandData.Flags &= ~(uint)ParcelFlags.ShowDirectory;
1153 // invalidate landing point
1154 newLand.LandData.LandingType = (byte)LandingType.Direct;
1155 newLand.LandData.UserLocation = Vector3.Zero;
1156 newLand.LandData.UserLookAt = Vector3.Zero;
1046 1157
1047 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y)); 1158 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y));
1048 1159
1049 //Now, lets set the subdivision area of the original to false 1160 //lets set the subdivision area of the original to false
1050 int startLandObjectIndex = startLandObject.LandData.LocalID; 1161 int startLandObjectIndex = startLandObject.LandData.LocalID;
1051 lock (m_landList) 1162 lock (m_landList)
1052 { 1163 {
@@ -1055,65 +1166,85 @@ namespace OpenSim.Region.CoreModules.World.Land
1055 m_landList[startLandObjectIndex].ForceUpdateLandInfo(); 1166 m_landList[startLandObjectIndex].ForceUpdateLandInfo();
1056 } 1167 }
1057 1168
1058 //Now add the new land object 1169 //add the new land object
1059 ILandObject result = AddLandObject(newLand); 1170 ILandObject result = AddLandObject(newLand);
1060 1171
1061 if (result != null) 1172 UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData);
1173
1174 if(startLandObject.LandData.LandingType == (byte)LandingType.LandingPoint)
1062 { 1175 {
1063 UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); 1176 int x = (int)startLandObject.LandData.UserLocation.X;
1064 result.SendLandUpdateToAvatarsOverMe(); 1177 int y = (int)startLandObject.LandData.UserLocation.Y;
1065 } 1178 if(!startLandObject.ContainsPoint(x, y))
1179 {
1180 startLandObject.LandData.LandingType = (byte)LandingType.Direct;
1181 startLandObject.LandData.UserLocation = Vector3.Zero;
1182 startLandObject.LandData.UserLookAt = Vector3.Zero;
1183 }
1184 }
1185
1186 m_scene.EventManager.TriggerParcelPrimCountTainted();
1187
1188 result.SendLandUpdateToAvatarsOverMe();
1189 startLandObject.SendLandUpdateToAvatarsOverMe();
1190 m_scene.ForEachClient(SendParcelOverlay);
1191
1066 } 1192 }
1067 1193
1068 /// <summary> 1194 /// <summary>
1069 /// Join 2 land objects together 1195 /// Join 2 land objects together
1070 /// </summary> 1196 /// </summary>
1071 /// <param name="start_x">x value in first piece of land</param> 1197 /// <param name="start_x">start x of selection area</param>
1072 /// <param name="start_y">y value in first piece of land</param> 1198 /// <param name="start_y">start y of selection area</param>
1073 /// <param name="end_x">x value in second peice of land</param> 1199 /// <param name="end_x">end x of selection area</param>
1074 /// <param name="end_y">y value in second peice of land</param> 1200 /// <param name="end_y">end y of selection area</param>
1075 /// <param name="attempting_user_id">UUID of the avatar trying to join the land objects</param> 1201 /// <param name="attempting_user_id">UUID of the avatar trying to join the land objects</param>
1076 /// <returns>Returns true if successful</returns> 1202 /// <returns>Returns true if successful</returns>
1077 private void join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) 1203 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
1078 { 1204 {
1079 end_x -= 4; 1205 int index = 0;
1080 end_y -= 4; 1206 int maxindex = -1;
1207 int maxArea = 0;
1081 1208
1082 List<ILandObject> selectedLandObjects = new List<ILandObject>(); 1209 List<ILandObject> selectedLandObjects = new List<ILandObject>();
1083 int stepYSelected; 1210 for (int x = start_x; x < end_x; x += 4)
1084 for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4)
1085 { 1211 {
1086 int stepXSelected; 1212 for (int y = start_y; y < end_y; y += 4)
1087 for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4)
1088 { 1213 {
1089 ILandObject p = GetLandObject(stepXSelected, stepYSelected); 1214 ILandObject p = GetLandObject(x, y);
1090 1215
1091 if (p != null) 1216 if (p != null)
1092 { 1217 {
1093 if (!selectedLandObjects.Contains(p)) 1218 if (!selectedLandObjects.Contains(p))
1094 { 1219 {
1095 selectedLandObjects.Add(p); 1220 selectedLandObjects.Add(p);
1221 if(p.LandData.Area > maxArea)
1222 {
1223 maxArea = p.LandData.Area;
1224 maxindex = index;
1225 }
1226 index++;
1096 } 1227 }
1097 } 1228 }
1098 } 1229 }
1099 } 1230 }
1100 ILandObject masterLandObject = selectedLandObjects[0];
1101 selectedLandObjects.RemoveAt(0);
1102 1231
1103 if (selectedLandObjects.Count < 1) 1232 if(maxindex < 0 || selectedLandObjects.Count < 2)
1104 {
1105 return; 1233 return;
1106 } 1234
1107 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin)) 1235 ILandObject masterLandObject = selectedLandObjects[maxindex];
1236 selectedLandObjects.RemoveAt(maxindex);
1237
1238 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin, true))
1108 { 1239 {
1109 return; 1240 return;
1110 } 1241 }
1242
1243 UUID masterOwner = masterLandObject.LandData.OwnerID;
1111 foreach (ILandObject p in selectedLandObjects) 1244 foreach (ILandObject p in selectedLandObjects)
1112 { 1245 {
1113 if (p.LandData.OwnerID != masterLandObject.LandData.OwnerID) 1246 if (p.LandData.OwnerID != masterOwner)
1114 {
1115 return; 1247 return;
1116 }
1117 } 1248 }
1118 1249
1119 lock (m_landList) 1250 lock (m_landList)
@@ -1126,29 +1257,14 @@ namespace OpenSim.Region.CoreModules.World.Land
1126 } 1257 }
1127 } 1258 }
1128 1259
1260 m_scene.EventManager.TriggerParcelPrimCountTainted();
1129 masterLandObject.SendLandUpdateToAvatarsOverMe(); 1261 masterLandObject.SendLandUpdateToAvatarsOverMe();
1262 m_scene.ForEachClient(SendParcelOverlay);
1130 } 1263 }
1131
1132 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
1133 {
1134 join(start_x, start_y, end_x, end_y, attempting_user_id);
1135 }
1136
1137 public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
1138 {
1139 subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
1140 }
1141
1142 #endregion 1264 #endregion
1143 1265
1144 #region Parcel Updating 1266 #region Parcel Updating
1145 1267
1146 // Send parcel layer info for the whole region
1147 public void SendParcelOverlay(IClientAPI remote_client)
1148 {
1149 SendParcelOverlay(remote_client, 0, 0, (int)Constants.MaximumRegionSize);
1150 }
1151
1152 /// <summary> 1268 /// <summary>
1153 /// Send the parcel overlay blocks to the client. We send the overlay packets 1269 /// Send the parcel overlay blocks to the client. We send the overlay packets
1154 /// around a location and limited by the 'parcelLayerViewDistance'. This number 1270 /// around a location and limited by the 'parcelLayerViewDistance'. This number
@@ -1162,145 +1278,115 @@ namespace OpenSim.Region.CoreModules.World.Land
1162 /// <param name="xPlace">X position in the region to send surrounding parcel layer info</param> 1278 /// <param name="xPlace">X position in the region to send surrounding parcel layer info</param>
1163 /// <param name="yPlace">y position in the region to send surrounding parcel layer info</param> 1279 /// <param name="yPlace">y position in the region to send surrounding parcel layer info</param>
1164 /// <param name="layerViewDistance">Distance from x,y position to send parcel layer info</param> 1280 /// <param name="layerViewDistance">Distance from x,y position to send parcel layer info</param>
1165 private void SendParcelOverlay(IClientAPI remote_client, int xPlace, int yPlace, int layerViewDistance) 1281 public void SendParcelOverlay(IClientAPI remote_client)
1166 { 1282 {
1283 if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
1284 return;
1285
1167 const int LAND_BLOCKS_PER_PACKET = 1024; 1286 const int LAND_BLOCKS_PER_PACKET = 1024;
1168 1287
1169 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1288 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1170 int byteArrayCount = 0; 1289 int byteArrayCount = 0;
1171 int sequenceID = 0; 1290 int sequenceID = 0;
1172 1291
1173 int xLow = 0; 1292 // Layer data is in LandUnit (4m) chunks
1174 int xHigh = (int)m_scene.RegionInfo.RegionSizeX; 1293 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y += LandUnit)
1175 int yLow = 0;
1176 int yHigh = (int)m_scene.RegionInfo.RegionSizeY;
1177
1178 if (shouldLimitParcelLayerInfoToViewDistance)
1179 { 1294 {
1180 // Compute view distance around the given point 1295 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x += LandUnit)
1181 int txLow = xPlace - layerViewDistance;
1182 int txHigh = xPlace + layerViewDistance;
1183 // If the distance is outside the region area, move the view distance to ba all in the region
1184 if (txLow < xLow)
1185 { 1296 {
1186 txLow = xLow; 1297 byte tempByte = 0; //This represents the byte for the current 4x4
1187 txHigh = Math.Min(yLow + (layerViewDistance * 2), xHigh);
1188 }
1189 if (txHigh > xHigh)
1190 {
1191 txLow = Math.Max(xLow, xHigh - (layerViewDistance * 2));
1192 txHigh = xHigh;
1193 }
1194 xLow = txLow;
1195 xHigh = txHigh;
1196 1298
1197 int tyLow = yPlace - layerViewDistance; 1299 ILandObject currentParcelBlock = GetLandObject(x, y);
1198 int tyHigh = yPlace + layerViewDistance;
1199 if (tyLow < yLow)
1200 {
1201 tyLow = yLow;
1202 tyHigh = Math.Min(yLow + (layerViewDistance * 2), yHigh);
1203 }
1204 if (tyHigh > yHigh)
1205 {
1206 tyLow = Math.Max(yLow, yHigh - (layerViewDistance * 2));
1207 tyHigh = yHigh;
1208 }
1209 yLow = tyLow;
1210 yHigh = tyHigh;
1211 }
1212 // m_log.DebugFormat("{0} SendParcelOverlay: place=<{1},{2}>, vDist={3}, xLH=<{4},{5}, yLH=<{6},{7}>",
1213 // LogHeader, xPlace, yPlace, layerViewDistance, xLow, xHigh, yLow, yHigh);
1214 1300
1215 // Layer data is in landUnit (4m) chunks 1301 if (currentParcelBlock != null)
1216 for (int y = yLow; y < yHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
1217 {
1218 for (int x = xLow; x < xHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
1219 {
1220 byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * LandUnit, y * LandUnit), x, y, remote_client);
1221 byteArrayCount++;
1222 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
1223 { 1302 {
1224 // m_log.DebugFormat("{0} SendParcelOverlay, sending packet, bytes={1}", LogHeader, byteArray.Length); 1303 // types
1225 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1304 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
1226 byteArrayCount = 0; 1305 {
1227 sequenceID++; 1306 //Owner Flag
1228 byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1307 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
1229 } 1308 }
1309 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1310 {
1311 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_GROUP;
1312 }
1313 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1314 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1315 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1316 {
1317 //Sale type
1318 tempByte = (byte)LandChannel.LAND_TYPE_IS_FOR_SALE;
1319 }
1320 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1321 {
1322 //Public type
1323 tempByte = (byte)LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero
1324 }
1325 // LAND_TYPE_IS_BEING_AUCTIONED still unsuported
1326 else
1327 {
1328 //Other Flag
1329 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_OTHER;
1330 }
1230 1331
1231 } 1332 // now flags
1232 } 1333 // border control
1233 1334
1234 if (byteArrayCount != 0) 1335 ILandObject westParcel = null;
1235 { 1336 ILandObject southParcel = null;
1236 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1337 if (x > 0)
1237 // m_log.DebugFormat("{0} SendParcelOverlay, complete sending packet, bytes={1}", LogHeader, byteArray.Length); 1338 {
1238 } 1339 westParcel = GetLandObject((x - 1), y);
1239 } 1340 }
1341 if (y > 0)
1342 {
1343 southParcel = GetLandObject(x, (y - 1));
1344 }
1240 1345
1241 private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client) 1346 if (x == 0)
1242 { 1347 {
1243 byte tempByte = 0; //This represents the byte for the current 4x4 1348 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
1349 }
1350 else if (westParcel != null && westParcel != currentParcelBlock)
1351 {
1352 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
1353 }
1244 1354
1245 if (currentParcelBlock != null) 1355 if (y == 0)
1246 { 1356 {
1247 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) 1357 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
1248 { 1358 }
1249 //Owner Flag 1359 else if (southParcel != null && southParcel != currentParcelBlock)
1250 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1360 {
1251 } 1361 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
1252 else if (currentParcelBlock.LandData.SalePrice > 0 && 1362 }
1253 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1254 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1255 {
1256 //Sale Flag
1257 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
1258 }
1259 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1260 {
1261 //Public Flag
1262 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
1263 }
1264 else
1265 {
1266 //Other Flag
1267 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
1268 }
1269 1363
1270 //Now for border control 1364 // local sound
1365 if ((currentParcelBlock.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
1366 tempByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
1271 1367
1272 ILandObject westParcel = null; 1368 // hide avatars
1273 ILandObject southParcel = null; 1369 if (!currentParcelBlock.LandData.SeeAVs)
1274 if (x > 0) 1370 tempByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS;
1275 {
1276 westParcel = GetLandObject((x - 1) * LandUnit, y * LandUnit);
1277 }
1278 if (y > 0)
1279 {
1280 southParcel = GetLandObject(x * LandUnit, (y - 1) * LandUnit);
1281 }
1282 1371
1283 if (x == 0)
1284 {
1285 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1286 }
1287 else if (westParcel != null && westParcel != currentParcelBlock)
1288 {
1289 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
1290 }
1291 1372
1292 if (y == 0) 1373 byteArray[byteArrayCount] = tempByte;
1293 { 1374 byteArrayCount++;
1294 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1375 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
1295 } 1376 {
1296 else if (southParcel != null && southParcel != currentParcelBlock) 1377 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1297 { 1378 byteArrayCount = 0;
1298 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1379 sequenceID++;
1380 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1381 }
1382 }
1299 } 1383 }
1300
1301 } 1384 }
1302 1385
1303 return tempByte; 1386 if (byteArrayCount > 0)
1387 {
1388 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1389 }
1304 } 1390 }
1305 1391
1306 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, 1392 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
@@ -1320,8 +1406,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1320 { 1406 {
1321 if (!temp.Contains(currentParcel)) 1407 if (!temp.Contains(currentParcel))
1322 { 1408 {
1323 currentParcel.ForceUpdateLandInfo(); 1409 if (!currentParcel.IsBannedFromLand(remote_client.AgentId))
1324 temp.Add(currentParcel); 1410 {
1411 currentParcel.ForceUpdateLandInfo();
1412 temp.Add(currentParcel);
1413 }
1325 } 1414 }
1326 } 1415 }
1327 } 1416 }
@@ -1338,8 +1427,44 @@ namespace OpenSim.Region.CoreModules.World.Land
1338 temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client); 1427 temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client);
1339 } 1428 }
1340 1429
1341 // Also send the layer data around the point of interest 1430// SendParcelOverlay(remote_client);
1342 SendParcelOverlay(remote_client, (start_x + end_x) / 2, (start_y + end_y) / 2, parcelLayerViewDistance); 1431 }
1432
1433 public void UpdateLandProperties(ILandObject land, LandUpdateArgs args, IClientAPI remote_client)
1434 {
1435 bool snap_selection = false;
1436 bool needOverlay = false;
1437 if (land.UpdateLandProperties(args, remote_client, out snap_selection, out needOverlay))
1438 {
1439 UUID parcelID = land.LandData.GlobalID;
1440 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
1441 {
1442 if (avatar.IsDeleted || avatar.IsNPC)
1443 return;
1444
1445 IClientAPI client = avatar.ControllingClient;
1446 if (needOverlay)
1447 SendParcelOverlay(client);
1448
1449 if (avatar.IsChildAgent)
1450 {
1451 if(client == remote_client)
1452 land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, client);
1453 return;
1454 }
1455
1456 ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
1457 if (aland != null)
1458 {
1459 if(client == remote_client && land != aland)
1460 land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, client);
1461 else if (land == aland)
1462 aland.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, client);
1463 }
1464 if (avatar.currentParcelUUID == parcelID)
1465 avatar.currentParcelUUID = parcelID; // force parcel flags review
1466 });
1467 }
1343 } 1468 }
1344 1469
1345 public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) 1470 public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client)
@@ -1352,19 +1477,19 @@ namespace OpenSim.Region.CoreModules.World.Land
1352 1477
1353 if (land != null) 1478 if (land != null)
1354 { 1479 {
1355 land.UpdateLandProperties(args, remote_client); 1480 UpdateLandProperties(land, args, remote_client);
1356 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client); 1481 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client);
1357 } 1482 }
1358 } 1483 }
1359 1484
1360 public void ClientOnParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) 1485 public void ClientOnParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
1361 { 1486 {
1362 subdivide(west, south, east, north, remote_client.AgentId); 1487 Subdivide(west, south, east, north, remote_client.AgentId);
1363 } 1488 }
1364 1489
1365 public void ClientOnParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client) 1490 public void ClientOnParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client)
1366 { 1491 {
1367 join(west, south, east, north, remote_client.AgentId); 1492 Join(west, south, east, north, remote_client.AgentId);
1368 } 1493 }
1369 1494
1370 public void ClientOnParcelSelectObjects(int local_id, int request_type, 1495 public void ClientOnParcelSelectObjects(int local_id, int request_type,
@@ -1375,7 +1500,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1375 1500
1376 public void ClientOnParcelObjectOwnerRequest(int local_id, IClientAPI remote_client) 1501 public void ClientOnParcelObjectOwnerRequest(int local_id, IClientAPI remote_client)
1377 { 1502 {
1378 ILandObject land; 1503 ILandObject land = null;
1379 lock (m_landList) 1504 lock (m_landList)
1380 { 1505 {
1381 m_landList.TryGetValue(local_id, out land); 1506 m_landList.TryGetValue(local_id, out land);
@@ -1384,7 +1509,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1384 if (land != null) 1509 if (land != null)
1385 { 1510 {
1386 m_scene.EventManager.TriggerParcelPrimCountUpdate(); 1511 m_scene.EventManager.TriggerParcelPrimCountUpdate();
1387 m_landList[local_id].SendLandObjectOwners(remote_client); 1512 land.SendLandObjectOwners(remote_client);
1388 } 1513 }
1389 else 1514 else
1390 { 1515 {
@@ -1394,7 +1519,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1394 1519
1395 public void ClientOnParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client) 1520 public void ClientOnParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client)
1396 { 1521 {
1397 ILandObject land; 1522 ILandObject land = null;
1398 lock (m_landList) 1523 lock (m_landList)
1399 { 1524 {
1400 m_landList.TryGetValue(local_id, out land); 1525 m_landList.TryGetValue(local_id, out land);
@@ -1408,7 +1533,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1408 land.LandData.GroupID = UUID.Zero; 1533 land.LandData.GroupID = UUID.Zero;
1409 land.LandData.IsGroupOwned = false; 1534 land.LandData.IsGroupOwned = false;
1410 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1535 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1411
1412 m_scene.ForEachClient(SendParcelOverlay); 1536 m_scene.ForEachClient(SendParcelOverlay);
1413 land.SendLandUpdateToClient(true, remote_client); 1537 land.SendLandUpdateToClient(true, remote_client);
1414 UpdateLandObject(land.LandData.LocalID, land.LandData); 1538 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1418,7 +1542,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1418 1542
1419 public void ClientOnParcelAbandonRequest(int local_id, IClientAPI remote_client) 1543 public void ClientOnParcelAbandonRequest(int local_id, IClientAPI remote_client)
1420 { 1544 {
1421 ILandObject land; 1545 ILandObject land = null;
1422 lock (m_landList) 1546 lock (m_landList)
1423 { 1547 {
1424 m_landList.TryGetValue(local_id, out land); 1548 m_landList.TryGetValue(local_id, out land);
@@ -1432,7 +1556,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1432 land.LandData.GroupID = UUID.Zero; 1556 land.LandData.GroupID = UUID.Zero;
1433 land.LandData.IsGroupOwned = false; 1557 land.LandData.IsGroupOwned = false;
1434 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1558 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1435 1559
1436 m_scene.ForEachClient(SendParcelOverlay); 1560 m_scene.ForEachClient(SendParcelOverlay);
1437 land.SendLandUpdateToClient(true, remote_client); 1561 land.SendLandUpdateToClient(true, remote_client);
1438 UpdateLandObject(land.LandData.LocalID, land.LandData); 1562 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1442,7 +1566,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1442 1566
1443 public void ClientOnParcelReclaim(int local_id, IClientAPI remote_client) 1567 public void ClientOnParcelReclaim(int local_id, IClientAPI remote_client)
1444 { 1568 {
1445 ILandObject land; 1569 ILandObject land = null;
1446 lock (m_landList) 1570 lock (m_landList)
1447 { 1571 {
1448 m_landList.TryGetValue(local_id, out land); 1572 m_landList.TryGetValue(local_id, out land);
@@ -1458,8 +1582,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1458 land.LandData.IsGroupOwned = false; 1582 land.LandData.IsGroupOwned = false;
1459 land.LandData.SalePrice = 0; 1583 land.LandData.SalePrice = 0;
1460 land.LandData.AuthBuyerID = UUID.Zero; 1584 land.LandData.AuthBuyerID = UUID.Zero;
1585 land.LandData.SeeAVs = true;
1586 land.LandData.AnyAVSounds = true;
1587 land.LandData.GroupAVSounds = true;
1461 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1588 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1462
1463 m_scene.ForEachClient(SendParcelOverlay); 1589 m_scene.ForEachClient(SendParcelOverlay);
1464 land.SendLandUpdateToClient(true, remote_client); 1590 land.SendLandUpdateToClient(true, remote_client);
1465 UpdateLandObject(land.LandData.LocalID, land.LandData); 1591 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1526,17 +1652,16 @@ namespace OpenSim.Region.CoreModules.World.Land
1526 1652
1527 void ClientOnParcelDeedToGroup(int parcelLocalID, UUID groupID, IClientAPI remote_client) 1653 void ClientOnParcelDeedToGroup(int parcelLocalID, UUID groupID, IClientAPI remote_client)
1528 { 1654 {
1529 ILandObject land; 1655 ILandObject land = null;
1530 lock (m_landList) 1656 lock (m_landList)
1531 { 1657 {
1532 m_landList.TryGetValue(parcelLocalID, out land); 1658 m_landList.TryGetValue(parcelLocalID, out land);
1533 } 1659 }
1534 1660
1535 if (!m_scene.Permissions.CanDeedParcel(remote_client.AgentId, land))
1536 return;
1537
1538 if (land != null) 1661 if (land != null)
1539 { 1662 {
1663 if (!m_scene.Permissions.CanDeedParcel(remote_client.AgentId, land))
1664 return;
1540 land.DeedToGroup(groupID); 1665 land.DeedToGroup(groupID);
1541 } 1666 }
1542 } 1667 }
@@ -1545,17 +1670,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1545 1670
1546 private void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1671 private void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1547 { 1672 {
1548// m_log.DebugFormat(
1549// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name);
1550
1551 // Prevent race conditions from any auto-creation of new parcels for varregions whilst we are still loading
1552 // the existing parcels.
1553 lock (m_landList) 1673 lock (m_landList)
1554 { 1674 {
1555 for (int i = 0; i < data.Count; i++) 1675 for (int i = 0; i < data.Count; i++)
1556 IncomingLandObjectFromStorage(data[i]); 1676 IncomingLandObjectFromStorage(data[i]);
1557 1677
1558 // Layer data is in landUnit (4m) chunks 1678 // Layer data is in LandUnit (4m) chunks
1559 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++) 1679 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
1560 { 1680 {
1561 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++) 1681 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
@@ -1565,7 +1685,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1565 if (m_landList.Count == 1) 1685 if (m_landList.Count == 1)
1566 { 1686 {
1567 m_log.DebugFormat( 1687 m_log.DebugFormat(
1568 "[{0}]: Auto-extending land parcel as landID at {1},{2} is 0 and only one land parcel is present in {3}", 1688 "[{0}]: Auto-extending land parcel as landID at {1},{2} is 0 and only one land parcel is present in {3}",
1569 LogHeader, x, y, m_scene.Name); 1689 LogHeader, x, y, m_scene.Name);
1570 1690
1571 int onlyParcelID = 0; 1691 int onlyParcelID = 0;
@@ -1588,11 +1708,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1588 else if (m_landList.Count > 1) 1708 else if (m_landList.Count > 1)
1589 { 1709 {
1590 m_log.DebugFormat( 1710 m_log.DebugFormat(
1591 "{0}: Auto-creating land parcel as landID at {1},{2} is 0 and more than one land parcel is present in {3}", 1711 "{0}: Auto-creating land parcel as landID at {1},{2} is 0 and more than one land parcel is present in {3}",
1592 LogHeader, x, y, m_scene.Name); 1712 LogHeader, x, y, m_scene.Name);
1593 1713
1594 // There are several other parcels so we must create a new one for the unassigned space 1714 // There are several other parcels so we must create a new one for the unassigned space
1595 ILandObject newLand = new LandObject(UUID.Zero, false, m_scene); 1715 ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
1596 // Claim all the unclaimed "0" ids 1716 // Claim all the unclaimed "0" ids
1597 newLand.SetLandBitmap(CreateBitmapForID(0)); 1717 newLand.SetLandBitmap(CreateBitmapForID(0));
1598 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 1718 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@@ -1603,20 +1723,23 @@ namespace OpenSim.Region.CoreModules.World.Land
1603 { 1723 {
1604 // We should never reach this point as the separate code path when no land data exists should have fired instead. 1724 // We should never reach this point as the separate code path when no land data exists should have fired instead.
1605 m_log.WarnFormat( 1725 m_log.WarnFormat(
1606 "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present", 1726 "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present",
1607 LogHeader, m_scene.Name); 1727 LogHeader, m_scene.Name);
1608 } 1728 }
1609 } 1729 }
1610 } 1730 }
1611 } 1731 }
1732 FinalizeLandPrimCountUpdate(); // update simarea information
1612 } 1733 }
1613 } 1734 }
1614 1735
1615 private void IncomingLandObjectFromStorage(LandData data) 1736 private void IncomingLandObjectFromStorage(LandData data)
1616 { 1737 {
1617 ILandObject new_land = new LandObject(data, m_scene); 1738 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene, data);
1618 new_land.SetLandBitmapFromByteArray(); 1739
1740 new_land.SetLandBitmapFromByteArray();
1619 AddLandObject(new_land); 1741 AddLandObject(new_land);
1742// new_land.SendLandUpdateToAvatarsOverMe();
1620 } 1743 }
1621 1744
1622 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1745 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1629,7 +1752,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1629 m_landList.TryGetValue(localID, out selectedParcel); 1752 m_landList.TryGetValue(localID, out selectedParcel);
1630 } 1753 }
1631 1754
1632 if (selectedParcel == null) 1755 if (selectedParcel == null)
1633 return; 1756 return;
1634 1757
1635 selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient); 1758 selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient);
@@ -1670,9 +1793,9 @@ namespace OpenSim.Region.CoreModules.World.Land
1670 foreach (HashSet<SceneObjectGroup> objs in returns.Values) 1793 foreach (HashSet<SceneObjectGroup> objs in returns.Values)
1671 { 1794 {
1672 List<SceneObjectGroup> objs2 = new List<SceneObjectGroup>(objs); 1795 List<SceneObjectGroup> objs2 = new List<SceneObjectGroup>(objs);
1673 if (m_scene.Permissions.CanReturnObjects(null, remoteClient.AgentId, objs2)) 1796 if (m_scene.Permissions.CanReturnObjects(null, remoteClient, objs2))
1674 { 1797 {
1675 m_scene.returnObjects(objs2.ToArray(), remoteClient.AgentId); 1798 m_scene.returnObjects(objs2.ToArray(), remoteClient);
1676 } 1799 }
1677 else 1800 else
1678 { 1801 {
@@ -1710,12 +1833,13 @@ namespace OpenSim.Region.CoreModules.World.Land
1710 1833
1711 private void EventManagerOnRegisterCaps(UUID agentID, Caps caps) 1834 private void EventManagerOnRegisterCaps(UUID agentID, Caps caps)
1712 { 1835 {
1836 //string capsBase = "/CAPS/" + UUID.Random();
1713 string capsBase = "/CAPS/" + caps.CapsObjectPath; 1837 string capsBase = "/CAPS/" + caps.CapsObjectPath;
1714 caps.RegisterHandler( 1838 caps.RegisterHandler(
1715 "RemoteParcelRequest", 1839 "RemoteParcelRequest",
1716 new RestStreamHandler( 1840 new RestStreamHandler(
1717 "POST", 1841 "POST",
1718 capsBase + remoteParcelRequestPath, 1842 capsBase,
1719 (request, path, param, httpRequest, httpResponse) 1843 (request, path, param, httpRequest, httpResponse)
1720 => RemoteParcelRequest(request, path, param, agentID, caps), 1844 => RemoteParcelRequest(request, path, param, agentID, caps),
1721 "RemoteParcelRequest", 1845 "RemoteParcelRequest",
@@ -1735,7 +1859,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1735 private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps) 1859 private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps)
1736 { 1860 {
1737 IClientAPI client; 1861 IClientAPI client;
1738 if (!m_scene.TryGetClient(agentID, out client)) 1862 if (!m_scene.TryGetClient(agentID, out client))
1739 { 1863 {
1740 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to retrieve IClientAPI for {0}", agentID); 1864 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to retrieve IClientAPI for {0}", agentID);
1741 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); 1865 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
@@ -1759,7 +1883,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1759 land_update.MusicURL = properties.MusicURL; 1883 land_update.MusicURL = properties.MusicURL;
1760 land_update.Name = properties.Name; 1884 land_update.Name = properties.Name;
1761 land_update.ParcelFlags = (uint) properties.ParcelFlags; 1885 land_update.ParcelFlags = (uint) properties.ParcelFlags;
1762 land_update.PassHours = (int) properties.PassHours; 1886 land_update.PassHours = properties.PassHours;
1763 land_update.PassPrice = (int) properties.PassPrice; 1887 land_update.PassPrice = (int) properties.PassPrice;
1764 land_update.SalePrice = (int) properties.SalePrice; 1888 land_update.SalePrice = (int) properties.SalePrice;
1765 land_update.SnapshotID = properties.SnapshotID; 1889 land_update.SnapshotID = properties.SnapshotID;
@@ -1773,7 +1897,20 @@ namespace OpenSim.Region.CoreModules.World.Land
1773 land_update.ObscureMusic = properties.ObscureMusic; 1897 land_update.ObscureMusic = properties.ObscureMusic;
1774 land_update.ObscureMedia = properties.ObscureMedia; 1898 land_update.ObscureMedia = properties.ObscureMedia;
1775 1899
1776 ILandObject land; 1900 if (args.ContainsKey("see_avs"))
1901 {
1902 land_update.SeeAVs = args["see_avs"].AsBoolean();
1903 land_update.AnyAVSounds = args["any_av_sounds"].AsBoolean();
1904 land_update.GroupAVSounds = args["group_av_sounds"].AsBoolean();
1905 }
1906 else
1907 {
1908 land_update.SeeAVs = true;
1909 land_update.AnyAVSounds = true;
1910 land_update.GroupAVSounds = true;
1911 }
1912
1913 ILandObject land = null;
1777 lock (m_landList) 1914 lock (m_landList)
1778 { 1915 {
1779 m_landList.TryGetValue(parcelID, out land); 1916 m_landList.TryGetValue(parcelID, out land);
@@ -1781,13 +1918,14 @@ namespace OpenSim.Region.CoreModules.World.Land
1781 1918
1782 if (land != null) 1919 if (land != null)
1783 { 1920 {
1784 land.UpdateLandProperties(land_update, client); 1921 UpdateLandProperties(land,land_update, client);
1785 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client); 1922 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client);
1786 } 1923 }
1787 else 1924 else
1788 { 1925 {
1789 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID); 1926 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID);
1790 } 1927 }
1928
1791 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); 1929 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
1792 } 1930 }
1793 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the 1931 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the
@@ -1815,9 +1953,9 @@ namespace OpenSim.Region.CoreModules.World.Land
1815 { 1953 {
1816 Hashtable hash = new Hashtable(); 1954 Hashtable hash = new Hashtable();
1817 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); 1955 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
1818 if (hash.ContainsKey("region_id") && hash.ContainsKey("location")) 1956 if (hash.ContainsKey("location"))
1819 { 1957 {
1820 UUID regionID = (UUID)hash["region_id"]; 1958 UUID scope = m_scene.RegionInfo.ScopeID;
1821 ArrayList list = (ArrayList)hash["location"]; 1959 ArrayList list = (ArrayList)hash["location"];
1822 uint x = (uint)(double)list[0]; 1960 uint x = (uint)(double)list[0];
1823 uint y = (uint)(double)list[1]; 1961 uint y = (uint)(double)list[1];
@@ -1826,19 +1964,46 @@ namespace OpenSim.Region.CoreModules.World.Land
1826 // if you do a "About Landmark" on a landmark a second time, the viewer sends the 1964 // if you do a "About Landmark" on a landmark a second time, the viewer sends the
1827 // region_handle it got earlier via RegionHandleRequest 1965 // region_handle it got earlier via RegionHandleRequest
1828 ulong regionHandle = Util.BytesToUInt64Big((byte[])hash["region_handle"]); 1966 ulong regionHandle = Util.BytesToUInt64Big((byte[])hash["region_handle"]);
1829 parcelID = Util.BuildFakeParcelID(regionHandle, x, y); 1967 if(regionHandle == m_scene.RegionInfo.RegionHandle)
1968 parcelID = Util.BuildFakeParcelID(regionHandle, x, y);
1969 else
1970 {
1971 uint wx;
1972 uint wy;
1973 Util.RegionHandleToWorldLoc(regionHandle, out wx, out wy);
1974 GridRegion info = m_scene.GridService.GetRegionByPosition(scope, (int)wx, (int)wy);
1975 if(info != null)
1976 {
1977 wx -= (uint)info.RegionLocX;
1978 wy -= (uint)info.RegionLocY;
1979 wx += x;
1980 wy += y;
1981 // Firestorm devs have no ideia how to do handlers math
1982 // on all cases
1983 if(wx > info.RegionSizeX || wy > info.RegionSizeY)
1984 {
1985 wx = x;
1986 wy = y;
1987 }
1988 parcelID = Util.BuildFakeParcelID(info.RegionHandle, wx, wy);
1989 }
1990 }
1830 } 1991 }
1831 else if (regionID == m_scene.RegionInfo.RegionID) 1992 else if(hash.ContainsKey("region_id"))
1832 { 1993 {
1994 UUID regionID = (UUID)hash["region_id"];
1995 if (regionID == m_scene.RegionInfo.RegionID)
1996 {
1833 // a parcel request for a local parcel => no need to query the grid 1997 // a parcel request for a local parcel => no need to query the grid
1834 parcelID = Util.BuildFakeParcelID(m_scene.RegionInfo.RegionHandle, x, y); 1998 parcelID = Util.BuildFakeParcelID(m_scene.RegionInfo.RegionHandle, x, y);
1835 } 1999 }
1836 else 2000 else
1837 { 2001 {
1838 // a parcel request for a parcel in another region. Ask the grid about the region 2002 // a parcel request for a parcel in another region. Ask the grid about the region
1839 GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, regionID); 2003 GridRegion info = m_scene.GridService.GetRegionByUUID(scope, regionID);
1840 if (info != null) 2004 if (info != null)
1841 parcelID = Util.BuildFakeParcelID(info.RegionHandle, x, y); 2005 parcelID = Util.BuildFakeParcelID(info.RegionHandle, x, y);
2006 }
1842 } 2007 }
1843 } 2008 }
1844 } 2009 }
@@ -1854,7 +2019,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1854 2019
1855 LLSDRemoteParcelResponse response = new LLSDRemoteParcelResponse(); 2020 LLSDRemoteParcelResponse response = new LLSDRemoteParcelResponse();
1856 response.parcel_id = parcelID; 2021 response.parcel_id = parcelID;
1857 m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelID {0}", parcelID); 2022 //m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelID {0}", parcelID);
1858 2023
1859 return LLSDHelpers.SerialiseLLSDReply(response); 2024 return LLSDHelpers.SerialiseLLSDReply(response);
1860 } 2025 }
@@ -1871,17 +2036,25 @@ namespace OpenSim.Region.CoreModules.World.Land
1871 { 2036 {
1872 UUID parcel = UUID.Zero; 2037 UUID parcel = UUID.Zero;
1873 UUID.TryParse(id, out parcel); 2038 UUID.TryParse(id, out parcel);
2039
1874 // assume we've got the parcelID we just computed in RemoteParcelRequest 2040 // assume we've got the parcelID we just computed in RemoteParcelRequest
1875 ExtendedLandData extLandData = new ExtendedLandData(); 2041 ExtendedLandData extLandData = new ExtendedLandData();
1876 Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle, 2042 if(!Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle,
1877 out extLandData.X, out extLandData.Y); 2043 out extLandData.X, out extLandData.Y))
1878 m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelinfo request for regionHandle {0}, x/y {1}/{2}", 2044 return null;
2045 m_log.DebugFormat("[LAND MANAGEMENT MODULE] : Got parcelinfo request for regionHandle {0}, x/y {1}/{2}",
1879 extLandData.RegionHandle, extLandData.X, extLandData.Y); 2046 extLandData.RegionHandle, extLandData.X, extLandData.Y);
1880 2047
1881 // for this region or for somewhere else? 2048 // for this region or for somewhere else?
1882 if (extLandData.RegionHandle == m_scene.RegionInfo.RegionHandle) 2049 if (extLandData.RegionHandle == m_scene.RegionInfo.RegionHandle)
1883 { 2050 {
1884 extLandData.LandData = this.GetLandObject(extLandData.X, extLandData.Y).LandData; 2051 ILandObject extLandObject = this.GetLandObject(extLandData.X, extLandData.Y);
2052 if(extLandObject == null)
2053 {
2054 m_log.DebugFormat("[LAND MANAGEMENT MODULE]: ParcelInfoRequest: a FakeParcelID points to outside the region");
2055 return null;
2056 }
2057 extLandData.LandData = extLandObject.LandData;
1885 extLandData.RegionAccess = m_scene.RegionInfo.AccessLevel; 2058 extLandData.RegionAccess = m_scene.RegionInfo.AccessLevel;
1886 } 2059 }
1887 else 2060 else
@@ -1907,6 +2080,9 @@ namespace OpenSim.Region.CoreModules.World.Land
1907 if (data.RegionHandle == m_scene.RegionInfo.RegionHandle) 2080 if (data.RegionHandle == m_scene.RegionInfo.RegionHandle)
1908 { 2081 {
1909 info = new GridRegion(m_scene.RegionInfo); 2082 info = new GridRegion(m_scene.RegionInfo);
2083 IDwellModule dwellModule = m_scene.RequestModuleInterface<IDwellModule>();
2084 if (dwellModule != null)
2085 data.LandData.Dwell = dwellModule.GetDwell(data.LandData);
1910 } 2086 }
1911 else 2087 else
1912 { 2088 {
@@ -1932,7 +2108,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1932 2108
1933 public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime) 2109 public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)
1934 { 2110 {
1935 ILandObject land; 2111 ILandObject land = null;
1936 lock (m_landList) 2112 lock (m_landList)
1937 { 2113 {
1938 m_landList.TryGetValue(localID, out land); 2114 m_landList.TryGetValue(localID, out land);
@@ -1940,14 +2116,91 @@ namespace OpenSim.Region.CoreModules.World.Land
1940 2116
1941 if (land == null) return; 2117 if (land == null) return;
1942 2118
1943 if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions)) 2119 if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions, false))
1944 return; 2120 return;
1945 2121
1946 land.LandData.OtherCleanTime = otherCleanTime; 2122 land.LandData.OtherCleanTime = otherCleanTime;
1947 2123
1948 UpdateLandObject(localID, land.LandData); 2124 UpdateLandObject(localID, land.LandData);
1949 } 2125 }
1950 2126
2127 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
2128 {
2129 ILandObject land = null;
2130 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
2131 foreach (ILandObject landObject in Land)
2132 {
2133 if (landObject.LandData.LocalID == landID)
2134 {
2135 land = landObject;
2136 }
2137 }
2138 land.DeedToGroup(DefaultGodParcelGroup);
2139 land.LandData.Name = DefaultGodParcelName;
2140 land.SendLandUpdateToAvatarsOverMe();
2141 }
2142
2143 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
2144 {
2145 ScenePresence SP;
2146 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
2147 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
2148 if (SP.GodController.UserLevel != 0)
2149 {
2150 if (flags == 0) //All parcels, scripted or not
2151 {
2152 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
2153 {
2154 if (e.OwnerID == targetID)
2155 {
2156 returns.Add(e);
2157 }
2158 }
2159 );
2160 }
2161 if (flags == 4) //All parcels, scripted object
2162 {
2163 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
2164 {
2165 if (e.OwnerID == targetID)
2166 {
2167 if (e.ContainsScripts())
2168 {
2169 returns.Add(e);
2170 }
2171 }
2172 });
2173 }
2174 if (flags == 4) //not target parcel, scripted object
2175 {
2176 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
2177 {
2178 if (e.OwnerID == targetID)
2179 {
2180 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
2181 if (landobject.LandData.OwnerID != e.OwnerID)
2182 {
2183 if (e.ContainsScripts())
2184 {
2185 returns.Add(e);
2186 }
2187 }
2188 }
2189 });
2190 }
2191 foreach (SceneObjectGroup ol in returns)
2192 {
2193 ReturnObject(ol, client);
2194 }
2195 }
2196 }
2197 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
2198 {
2199 SceneObjectGroup[] objs = new SceneObjectGroup[1];
2200 objs[0] = obj;
2201 ((Scene)client.Scene).returnObjects(objs, client);
2202 }
2203
1951 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); 2204 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1952 2205
1953 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 2206 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
@@ -1958,12 +2211,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1958 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); 2211 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager);
1959 System.Threading.Timer Timer; 2212 System.Threading.Timer Timer;
1960 2213
1961 if (targetAvatar.UserLevel == 0) 2214 if (targetAvatar.GodController.UserLevel < 200)
1962 { 2215 {
1963 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); 2216 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1964 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze)) 2217 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true))
1965 return; 2218 return;
1966 if (flags == 0) 2219 if ((flags & 1) == 0) // only lowest bit has meaning for now
1967 { 2220 {
1968 targetAvatar.AllowMovement = false; 2221 targetAvatar.AllowMovement = false;
1969 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world."); 2222 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world.");
@@ -1983,7 +2236,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1983 } 2236 }
1984 } 2237 }
1985 } 2238 }
1986
1987 private void OnEndParcelFrozen(object avatar) 2239 private void OnEndParcelFrozen(object avatar)
1988 { 2240 {
1989 ScenePresence targetAvatar = (ScenePresence)avatar; 2241 ScenePresence targetAvatar = (ScenePresence)avatar;
@@ -2010,12 +2262,13 @@ namespace OpenSim.Region.CoreModules.World.Land
2010 2262
2011 // Check if you even have permission to do this 2263 // Check if you even have permission to do this
2012 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); 2264 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
2013 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && 2265 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true) &&
2014 !m_scene.Permissions.IsAdministrator(client.AgentId)) 2266 !m_scene.Permissions.IsAdministrator(client.AgentId))
2015 return; 2267 return;
2268
2016 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); 2269 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
2017 2270
2018 targetAvatar.TeleportWithMomentum(pos, null); 2271 targetAvatar.TeleportOnEject(pos);
2019 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); 2272 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
2020 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); 2273 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
2021 2274
@@ -2059,7 +2312,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2059 if (// Required: local user; foreign users cannot set home 2312 if (// Required: local user; foreign users cannot set home
2060 m_scene.UserManagementModule.IsLocalGridUser(remoteClient.AgentId) && 2313 m_scene.UserManagementModule.IsLocalGridUser(remoteClient.AgentId) &&
2061 (// (a) gods and land managers can set home 2314 (// (a) gods and land managers can set home
2062 m_scene.Permissions.IsAdministrator(remoteClient.AgentId) || 2315 m_scene.Permissions.IsAdministrator(remoteClient.AgentId) ||
2063 m_scene.Permissions.IsGod(remoteClient.AgentId) || 2316 m_scene.Permissions.IsGod(remoteClient.AgentId) ||
2064 // (b) land owners can set home 2317 // (b) land owners can set home
2065 remoteClient.AgentId == land.LandData.OwnerID || 2318 remoteClient.AgentId == land.LandData.OwnerID ||
@@ -2111,8 +2364,8 @@ namespace OpenSim.Region.CoreModules.World.Land
2111 "If no local land ID is given, then summary information about all the parcels is shown.\n" 2364 "If no local land ID is given, then summary information about all the parcels is shown.\n"
2112 + "If a local land ID is given then full information about that parcel is shown.", 2365 + "If a local land ID is given then full information about that parcel is shown.",
2113 HandleShowCommand); 2366 HandleShowCommand);
2114 } 2367 }
2115 2368
2116 protected void HandleClearCommand(string module, string[] args) 2369 protected void HandleClearCommand(string module, string[] args)
2117 { 2370 {
2118 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) 2371 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
@@ -2120,9 +2373,9 @@ namespace OpenSim.Region.CoreModules.World.Land
2120 2373
2121 string response = MainConsole.Instance.CmdPrompt( 2374 string response = MainConsole.Instance.CmdPrompt(
2122 string.Format( 2375 string.Format(
2123 "Are you sure that you want to clear all land parcels from {0} (y or n)", m_scene.Name), 2376 "Are you sure that you want to clear all land parcels from {0} (y or n)", m_scene.Name),
2124 "n"); 2377 "n");
2125 2378
2126 if (response.ToLower() == "y") 2379 if (response.ToLower() == "y")
2127 { 2380 {
2128 Clear(true); 2381 Clear(true);
@@ -2132,14 +2385,14 @@ namespace OpenSim.Region.CoreModules.World.Land
2132 { 2385 {
2133 MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.Name); 2386 MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.Name);
2134 } 2387 }
2135 } 2388 }
2136 2389
2137 protected void HandleShowCommand(string module, string[] args) 2390 protected void HandleShowCommand(string module, string[] args)
2138 { 2391 {
2139 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) 2392 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
2140 return; 2393 return;
2141 2394
2142 StringBuilder report = new StringBuilder(); 2395 StringBuilder report = new StringBuilder();
2143 2396
2144 if (args.Length <= 2) 2397 if (args.Length <= 2)
2145 { 2398 {
@@ -2152,10 +2405,10 @@ namespace OpenSim.Region.CoreModules.World.Land
2152 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[2], out landLocalId)) 2405 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[2], out landLocalId))
2153 return; 2406 return;
2154 2407
2155 ILandObject lo; 2408 ILandObject lo = null;
2156 2409
2157 lock (m_landList) 2410 lock (m_landList)
2158 { 2411 {
2159 if (!m_landList.TryGetValue(landLocalId, out lo)) 2412 if (!m_landList.TryGetValue(landLocalId, out lo))
2160 { 2413 {
2161 MainConsole.Instance.OutputFormat("No parcel found with local ID {0}", landLocalId); 2414 MainConsole.Instance.OutputFormat("No parcel found with local ID {0}", landLocalId);
@@ -2170,7 +2423,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2170 } 2423 }
2171 2424
2172 private void AppendParcelsSummaryReport(StringBuilder report) 2425 private void AppendParcelsSummaryReport(StringBuilder report)
2173 { 2426 {
2174 report.AppendFormat("Land information for {0}\n", m_scene.Name); 2427 report.AppendFormat("Land information for {0}\n", m_scene.Name);
2175 2428
2176 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 2429 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
@@ -2180,7 +2433,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2180 cdt.AddColumn("Starts", ConsoleDisplayUtil.VectorSize); 2433 cdt.AddColumn("Starts", ConsoleDisplayUtil.VectorSize);
2181 cdt.AddColumn("Ends", ConsoleDisplayUtil.VectorSize); 2434 cdt.AddColumn("Ends", ConsoleDisplayUtil.VectorSize);
2182 cdt.AddColumn("Owner", ConsoleDisplayUtil.UserNameSize); 2435 cdt.AddColumn("Owner", ConsoleDisplayUtil.UserNameSize);
2183 2436
2184 lock (m_landList) 2437 lock (m_landList)
2185 { 2438 {
2186 foreach (ILandObject lo in m_landList.Values) 2439 foreach (ILandObject lo in m_landList.Values)
@@ -2202,7 +2455,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2202 } 2455 }
2203 2456
2204 report.Append(cdt.ToString()); 2457 report.Append(cdt.ToString());
2205 } 2458 }
2206 2459
2207 private void AppendParcelReport(StringBuilder report, ILandObject lo) 2460 private void AppendParcelReport(StringBuilder report, ILandObject lo)
2208 { 2461 {
@@ -2214,8 +2467,6 @@ namespace OpenSim.Region.CoreModules.World.Land
2214 cdl.AddRow("Description", ld.Description); 2467 cdl.AddRow("Description", ld.Description);
2215 cdl.AddRow("Snapshot ID", ld.SnapshotID); 2468 cdl.AddRow("Snapshot ID", ld.SnapshotID);
2216 cdl.AddRow("Area", ld.Area); 2469 cdl.AddRow("Area", ld.Area);
2217 cdl.AddRow("Starts", lo.StartPoint);
2218 cdl.AddRow("Ends", lo.EndPoint);
2219 cdl.AddRow("AABB Min", ld.AABBMin); 2470 cdl.AddRow("AABB Min", ld.AABBMin);
2220 cdl.AddRow("AABB Max", ld.AABBMax); 2471 cdl.AddRow("AABB Max", ld.AABBMax);
2221 string ownerName; 2472 string ownerName;
@@ -2233,7 +2484,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2233 cdl.AddRow("GroupID", ld.GroupID); 2484 cdl.AddRow("GroupID", ld.GroupID);
2234 2485
2235 cdl.AddRow("Status", ld.Status); 2486 cdl.AddRow("Status", ld.Status);
2236 cdl.AddRow("Flags", (ParcelFlags)ld.Flags); 2487 cdl.AddRow("Flags", (ParcelFlags)ld.Flags);
2237 2488
2238 cdl.AddRow("Landing Type", (LandingType)ld.LandingType); 2489 cdl.AddRow("Landing Type", (LandingType)ld.LandingType);
2239 cdl.AddRow("User Location", ld.UserLocation); 2490 cdl.AddRow("User Location", ld.UserLocation);
@@ -2242,12 +2493,14 @@ namespace OpenSim.Region.CoreModules.World.Land
2242 cdl.AddRow("Other clean time", ld.OtherCleanTime); 2493 cdl.AddRow("Other clean time", ld.OtherCleanTime);
2243 2494
2244 cdl.AddRow("Max Prims", lo.GetParcelMaxPrimCount()); 2495 cdl.AddRow("Max Prims", lo.GetParcelMaxPrimCount());
2496 cdl.AddRow("Simwide Max Prims (owner)", lo.GetSimulatorMaxPrimCount());
2245 IPrimCounts pc = lo.PrimCounts; 2497 IPrimCounts pc = lo.PrimCounts;
2246 cdl.AddRow("Owner Prims", pc.Owner); 2498 cdl.AddRow("Owner Prims", pc.Owner);
2247 cdl.AddRow("Group Prims", pc.Group); 2499 cdl.AddRow("Group Prims", pc.Group);
2248 cdl.AddRow("Other Prims", pc.Others); 2500 cdl.AddRow("Other Prims", pc.Others);
2249 cdl.AddRow("Selected Prims", pc.Selected); 2501 cdl.AddRow("Selected Prims", pc.Selected);
2250 cdl.AddRow("Total Prims", pc.Total); 2502 cdl.AddRow("Total Prims", pc.Total);
2503 cdl.AddRow("SimWide Prims (owner)", pc.Simulator);
2251 2504
2252 cdl.AddRow("Music URL", ld.MusicURL); 2505 cdl.AddRow("Music URL", ld.MusicURL);
2253 cdl.AddRow("Obscure Music", ld.ObscureMusic); 2506 cdl.AddRow("Obscure Music", ld.ObscureMusic);
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index a0c1b9d..4471432 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -50,15 +50,22 @@ namespace OpenSim.Region.CoreModules.World.Land
50 private readonly int landUnit = 4; 50 private readonly int landUnit = 4;
51 51
52 private int m_lastSeqId = 0; 52 private int m_lastSeqId = 0;
53 53 private int m_expiryCounter = 0;
54
54 protected Scene m_scene; 55 protected Scene m_scene;
55 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); 56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
56 protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); 57 protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
57 58
58 protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>(); 59 protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>();
59 protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds 60 protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds
61 IDwellModule m_dwellModule;
60 62
61 public bool[,] LandBitmap { get; set; } 63 private bool[,] m_landBitmap;
64 public bool[,] LandBitmap
65 {
66 get { return m_landBitmap; }
67 set { m_landBitmap = value; }
68 }
62 69
63 #endregion 70 #endregion
64 71
@@ -69,7 +76,13 @@ namespace OpenSim.Region.CoreModules.World.Land
69 return free; 76 return free;
70 } 77 }
71 78
72 public LandData LandData { get; set; } 79 protected LandData m_landData;
80 public LandData LandData
81 {
82 get { return m_landData; }
83
84 set { m_landData = value; }
85 }
73 86
74 public IPrimCounts PrimCounts { get; set; } 87 public IPrimCounts PrimCounts { get; set; }
75 88
@@ -78,77 +91,230 @@ namespace OpenSim.Region.CoreModules.World.Land
78 get { return m_scene.RegionInfo.RegionID; } 91 get { return m_scene.RegionInfo.RegionID; }
79 } 92 }
80 93
81 public Vector3 StartPoint 94 private Vector2 m_startPoint = Vector2.Zero;
95 private Vector2 m_endPoint = Vector2.Zero;
96 private Vector2 m_centerPoint = Vector2.Zero;
97 private Vector2 m_AABBmin = Vector2.Zero;
98 private Vector2 m_AABBmax = Vector2.Zero;
99
100 public Vector2 StartPoint
82 { 101 {
83 get 102 get
84 { 103 {
85 for (int y = 0; y < LandBitmap.GetLength(1); y++) 104 return m_startPoint;
86 { 105 }
87 for (int x = 0; x < LandBitmap.GetLength(0); x++) 106 }
88 {
89 if (LandBitmap[x, y])
90 return new Vector3(x * landUnit, y * landUnit, 0);
91 }
92 }
93 107
94 m_log.ErrorFormat("{0} StartPoint. No start point found. bitmapSize=<{1},{2}>", 108 public Vector2 EndPoint
95 LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); 109 {
96 return new Vector3(-1, -1, -1); 110 get
111 {
112 return m_endPoint;
97 } 113 }
98 } 114 }
99 115
100 public Vector3 EndPoint 116 //estimate a center point of a parcel
117 public Vector2 CenterPoint
101 { 118 {
102 get 119 get
103 { 120 {
104 for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--) 121 return m_centerPoint;
122 }
123 }
124
125 public Vector2? GetNearestPoint(Vector3 pos)
126 {
127 Vector3 direction = new Vector3(m_centerPoint.X - pos.X, m_centerPoint.Y - pos.Y, 0f );
128 return GetNearestPointAlongDirection(pos, direction);
129 }
130
131 public Vector2? GetNearestPointAlongDirection(Vector3 pos, Vector3 pdirection)
132 {
133 Vector2 testpos;
134 Vector2 direction;
135
136 testpos.X = pos.X / landUnit;
137 testpos.Y = pos.Y / landUnit;
138
139 if(LandBitmap[(int)testpos.X, (int)testpos.Y])
140 return new Vector2(pos.X, pos.Y); // we are already here
141
142 direction.X = pdirection.X;
143 direction.Y = pdirection.Y;
144
145 if(direction.X == 0f && direction.Y == 0f)
146 return null; // we can't look anywhere
147
148 direction.Normalize();
149
150 int minx = (int)(m_AABBmin.X / landUnit);
151 int maxx = (int)(m_AABBmax.X / landUnit);
152
153 // check against AABB
154 if(direction.X > 0f)
155 {
156 if(testpos.X >= maxx)
157 return null; // will never get there
158 if(testpos.X < minx)
159 testpos.X = minx;
160 }
161 else if(direction.X < 0f)
162 {
163 if(testpos.X < minx)
164 return null; // will never get there
165 if(testpos.X >= maxx)
166 testpos.X = maxx - 1;
167 }
168 else
169 {
170 if(testpos.X < minx)
171 return null; // will never get there
172 else if(testpos.X >= maxx)
173 return null; // will never get there
174 }
175
176 int miny = (int)(m_AABBmin.Y / landUnit);
177 int maxy = (int)(m_AABBmax.Y / landUnit);
178
179 if(direction.Y > 0f)
180 {
181 if(testpos.Y >= maxy)
182 return null; // will never get there
183 if(testpos.Y < miny)
184 testpos.Y = miny;
185 }
186 else if(direction.Y < 0f)
187 {
188 if(testpos.Y < miny)
189 return null; // will never get there
190 if(testpos.Y >= maxy)
191 testpos.Y = maxy - 1;
192 }
193 else
194 {
195 if(testpos.Y < miny)
196 return null; // will never get there
197 else if(testpos.Y >= maxy)
198 return null; // will never get there
199 }
200
201 while(!LandBitmap[(int)testpos.X, (int)testpos.Y])
202 {
203 testpos += direction;
204
205 if(testpos.X < minx)
206 return null;
207 if (testpos.X >= maxx)
208 return null;
209 if(testpos.Y < miny)
210 return null;
211 if (testpos.Y >= maxy)
212 return null;
213 }
214
215 testpos *= landUnit;
216 float ftmp;
217
218 if(Math.Abs(direction.X) > Math.Abs(direction.Y))
219 {
220 if(direction.X < 0)
221 testpos.X += landUnit - 0.5f;
222 else
223 testpos.X += 0.5f;
224 ftmp = testpos.X - pos.X;
225 ftmp /= direction.X;
226 ftmp = Math.Abs(ftmp);
227 ftmp *= direction.Y;
228 ftmp += pos.Y;
229
230 if(ftmp < testpos.Y + .5f)
231 ftmp = testpos.Y + .5f;
232 else
105 { 233 {
106 for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--) 234 testpos.Y += landUnit - 0.5f;
107 { 235 if(ftmp > testpos.Y)
108 if (LandBitmap[x, y]) 236 ftmp = testpos.Y;
109 {
110 return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0);
111 }
112 }
113 } 237 }
114 238 testpos.Y = ftmp;
115 m_log.ErrorFormat("{0} EndPoint. No end point found. bitmapSize=<{1},{2}>", 239 }
116 LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); 240 else
117 return new Vector3(-1, -1, -1); 241 {
242 if(direction.Y < 0)
243 testpos.Y += landUnit - 0.5f;
244 else
245 testpos.Y += 0.5f;
246 ftmp = testpos.Y - pos.Y;
247 ftmp /= direction.Y;
248 ftmp = Math.Abs(ftmp);
249 ftmp *= direction.X;
250 ftmp += pos.X;
251
252 if(ftmp < testpos.X + .5f)
253 ftmp = testpos.X + .5f;
254 else
255 {
256 testpos.X += landUnit - 0.5f;
257 if(ftmp > testpos.X)
258 ftmp = testpos.X;
259 }
260 testpos.X = ftmp;
118 } 261 }
262 return testpos;
119 } 263 }
120 264
265
121 #region Constructors 266 #region Constructors
122 267
123 public LandObject(LandData landData, Scene scene) 268 public LandObject(LandData landData, Scene scene)
124 { 269 {
125 LandData = landData.Copy(); 270 LandData = landData.Copy();
126 m_scene = scene; 271 m_scene = scene;
272 m_scene.EventManager.OnFrame += OnFrame;
273 m_dwellModule = m_scene.RequestModuleInterface<IDwellModule>();
127 } 274 }
128 275
129 public LandObject(UUID owner_id, bool is_group_owned, Scene scene) 276 public LandObject(UUID owner_id, bool is_group_owned, Scene scene, LandData data = null)
130 { 277 {
131 m_scene = scene; 278 m_scene = scene;
132 if (m_scene == null) 279 if (m_scene == null)
133 LandBitmap = new bool[Constants.RegionSize / landUnit, Constants.RegionSize / landUnit]; 280 LandBitmap = new bool[Constants.RegionSize / landUnit, Constants.RegionSize / landUnit];
134 else 281 else
282 {
135 LandBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; 283 LandBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
284 m_dwellModule = m_scene.RequestModuleInterface<IDwellModule>();
285 }
286
287 if(data == null)
288 LandData = new LandData();
289 else
290 LandData = data;
136 291
137 LandData = new LandData();
138 LandData.OwnerID = owner_id; 292 LandData.OwnerID = owner_id;
139 if (is_group_owned) 293 if (is_group_owned)
140 LandData.GroupID = owner_id; 294 LandData.GroupID = owner_id;
141 else 295
142 LandData.GroupID = UUID.Zero;
143 LandData.IsGroupOwned = is_group_owned; 296 LandData.IsGroupOwned = is_group_owned;
297
298 if(m_dwellModule == null)
299 LandData.Dwell = 0;
300
301 m_scene.EventManager.OnFrame += OnFrame;
302 }
303
304 public void Clear()
305 {
306 if(m_scene != null)
307 m_scene.EventManager.OnFrame -= OnFrame;
308 LandData = null;
144 } 309 }
145 310
311
146 #endregion 312 #endregion
147 313
148 #region Member Functions 314 #region Member Functions
149 315
150 #region General Functions 316 #region General Functions
151 317
152 /// <summary> 318 /// <summary>
153 /// Checks to see if this land object contains a point 319 /// Checks to see if this land object contains a point
154 /// </summary> 320 /// </summary>
@@ -195,14 +361,22 @@ namespace OpenSim.Region.CoreModules.World.Land
195 else 361 else
196 { 362 {
197 // Normal Calculations 363 // Normal Calculations
198 int parcelMax = (int)(((float)LandData.Area / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)) 364 int parcelMax = (int)(
199 * (float)m_scene.RegionInfo.ObjectCapacity 365 (double)LandData.Area
200 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 366 * (double)m_scene.RegionInfo.ObjectCapacity
201 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! 367 * (double)m_scene.RegionInfo.RegionSettings.ObjectBonus
368 / (double)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)
369 + 0.5 );
370
371 if(parcelMax > m_scene.RegionInfo.ObjectCapacity)
372 parcelMax = m_scene.RegionInfo.ObjectCapacity;
373
374 //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax);
202 return parcelMax; 375 return parcelMax;
203 } 376 }
204 } 377 }
205 378
379 // the total prims a parcel owner can have on a region
206 public int GetSimulatorMaxPrimCount() 380 public int GetSimulatorMaxPrimCount()
207 { 381 {
208 if (overrideSimulatorMaxPrimCount != null) 382 if (overrideSimulatorMaxPrimCount != null)
@@ -212,18 +386,34 @@ namespace OpenSim.Region.CoreModules.World.Land
212 else 386 else
213 { 387 {
214 //Normal Calculations 388 //Normal Calculations
215 int simMax = (int)(((float)LandData.SimwideArea / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)) 389 int simMax = (int)( (double)LandData.SimwideArea
216 * (float)m_scene.RegionInfo.ObjectCapacity); 390 * (double)m_scene.RegionInfo.ObjectCapacity
391 * (double)m_scene.RegionInfo.RegionSettings.ObjectBonus
392 / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)
393 +0.5 );
394 // sanity check
395 if(simMax > m_scene.RegionInfo.ObjectCapacity)
396 simMax = m_scene.RegionInfo.ObjectCapacity;
397 //m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}, SimWidePrims {3}",
398 // LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax, LandData.SimwidePrims);
217 return simMax; 399 return simMax;
218 } 400 }
219 } 401 }
220 402
221 #endregion 403 #endregion
222 404
223 #region Packet Request Handling 405 #region Packet Request Handling
224 406
225 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) 407 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
226 { 408 {
409 if(m_scene.RegionInfo.RegionSettings.AllowDamage)
410 remote_client.SceneAgent.Invulnerable = false;
411 else
412 remote_client.SceneAgent.Invulnerable = (m_landData.Flags & (uint)ParcelFlags.AllowDamage) == 0;
413
414 if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
415 return;
416
227 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 417 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
228 // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); 418 // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
229 uint regionFlags = (uint)(RegionFlags.PublicAllowed 419 uint regionFlags = (uint)(RegionFlags.PublicAllowed
@@ -252,10 +442,11 @@ namespace OpenSim.Region.CoreModules.World.Land
252 GetSimulatorMaxPrimCount(), regionFlags); 442 GetSimulatorMaxPrimCount(), regionFlags);
253 } 443 }
254 444
255 public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) 445 public bool UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client, out bool snap_selection, out bool needOverlay)
256 { 446 {
257 //Needs later group support 447 //Needs later group support
258 bool snap_selection = false; 448 snap_selection = false;
449 needOverlay = false;
259 LandData newData = LandData.Copy(); 450 LandData newData = LandData.Copy();
260 451
261 uint allowedDelta = 0; 452 uint allowedDelta = 0;
@@ -264,7 +455,7 @@ namespace OpenSim.Region.CoreModules.World.Land
264 // ParcelFlags.ForSaleObjects 455 // ParcelFlags.ForSaleObjects
265 // ParcelFlags.LindenHome 456 // ParcelFlags.LindenHome
266 457
267 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) 458 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, false))
268 { 459 {
269 allowedDelta |= (uint)(ParcelFlags.AllowLandmark | 460 allowedDelta |= (uint)(ParcelFlags.AllowLandmark |
270 ParcelFlags.AllowTerraform | 461 ParcelFlags.AllowTerraform |
@@ -277,9 +468,12 @@ namespace OpenSim.Region.CoreModules.World.Land
277 ParcelFlags.AllowAPrimitiveEntry | 468 ParcelFlags.AllowAPrimitiveEntry |
278 ParcelFlags.AllowGroupObjectEntry | 469 ParcelFlags.AllowGroupObjectEntry |
279 ParcelFlags.AllowFly); 470 ParcelFlags.AllowFly);
471 newData.SeeAVs = args.SeeAVs;
472 newData.AnyAVSounds = args.AnyAVSounds;
473 newData.GroupAVSounds = args.GroupAVSounds;
280 } 474 }
281 475
282 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale)) 476 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale, true))
283 { 477 {
284 if (args.AuthBuyerID != newData.AuthBuyerID || 478 if (args.AuthBuyerID != newData.AuthBuyerID ||
285 args.SalePrice != newData.SalePrice) 479 args.SalePrice != newData.SalePrice)
@@ -302,30 +496,30 @@ namespace OpenSim.Region.CoreModules.World.Land
302 allowedDelta |= (uint)ParcelFlags.ForSale; 496 allowedDelta |= (uint)ParcelFlags.ForSale;
303 } 497 }
304 498
305 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces)) 499 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces, false))
306 { 500 {
307 newData.Category = args.Category; 501 newData.Category = args.Category;
308 502
309 allowedDelta |= (uint)(ParcelFlags.ShowDirectory | 503 allowedDelta |= (uint)(ParcelFlags.ShowDirectory |
310 ParcelFlags.AllowPublish | 504 ParcelFlags.AllowPublish |
311 ParcelFlags.MaturePublish); 505 ParcelFlags.MaturePublish) | (uint)(1 << 23);
312 } 506 }
313 507
314 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) 508 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity, false))
315 { 509 {
316 newData.Description = args.Desc; 510 newData.Description = args.Desc;
317 newData.Name = args.Name; 511 newData.Name = args.Name;
318 newData.SnapshotID = args.SnapshotID; 512 newData.SnapshotID = args.SnapshotID;
319 } 513 }
320 514
321 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint)) 515 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint, false))
322 { 516 {
323 newData.LandingType = args.LandingType; 517 newData.LandingType = args.LandingType;
324 newData.UserLocation = args.UserLocation; 518 newData.UserLocation = args.UserLocation;
325 newData.UserLookAt = args.UserLookAt; 519 newData.UserLookAt = args.UserLookAt;
326 } 520 }
327 521
328 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia)) 522 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia, false))
329 { 523 {
330 newData.MediaAutoScale = args.MediaAutoScale; 524 newData.MediaAutoScale = args.MediaAutoScale;
331 newData.MediaID = args.MediaID; 525 newData.MediaID = args.MediaID;
@@ -346,7 +540,8 @@ namespace OpenSim.Region.CoreModules.World.Land
346 ParcelFlags.UseEstateVoiceChan); 540 ParcelFlags.UseEstateVoiceChan);
347 } 541 }
348 542
349 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses)) 543 // don't allow passes on group owned until we can give money to groups
544 if (!newData.IsGroupOwned && m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false))
350 { 545 {
351 newData.PassHours = args.PassHours; 546 newData.PassHours = args.PassHours;
352 newData.PassPrice = args.PassPrice; 547 newData.PassPrice = args.PassPrice;
@@ -354,13 +549,13 @@ namespace OpenSim.Region.CoreModules.World.Land
354 allowedDelta |= (uint)ParcelFlags.UsePassList; 549 allowedDelta |= (uint)ParcelFlags.UsePassList;
355 } 550 }
356 551
357 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed)) 552 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed, false))
358 { 553 {
359 allowedDelta |= (uint)(ParcelFlags.UseAccessGroup | 554 allowedDelta |= (uint)(ParcelFlags.UseAccessGroup |
360 ParcelFlags.UseAccessList); 555 ParcelFlags.UseAccessList);
361 } 556 }
362 557
363 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned)) 558 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned, false))
364 { 559 {
365 allowedDelta |= (uint)(ParcelFlags.UseBanList | 560 allowedDelta |= (uint)(ParcelFlags.UseBanList |
366 ParcelFlags.DenyAnonymous | 561 ParcelFlags.DenyAnonymous |
@@ -372,9 +567,16 @@ namespace OpenSim.Region.CoreModules.World.Land
372 uint preserve = LandData.Flags & ~allowedDelta; 567 uint preserve = LandData.Flags & ~allowedDelta;
373 newData.Flags = preserve | (args.ParcelFlags & allowedDelta); 568 newData.Flags = preserve | (args.ParcelFlags & allowedDelta);
374 569
570 uint curdelta = LandData.Flags ^ newData.Flags;
571 curdelta &= (uint)(ParcelFlags.SoundLocal);
572
573 if(curdelta != 0 || newData.SeeAVs != LandData.SeeAVs)
574 needOverlay = true;
575
375 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 576 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
376 SendLandUpdateToAvatarsOverMe(snap_selection); 577 return true;
377 } 578 }
579 return false;
378 } 580 }
379 581
380 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) 582 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
@@ -395,7 +597,7 @@ namespace OpenSim.Region.CoreModules.World.Land
395 UUID previousOwner = LandData.OwnerID; 597 UUID previousOwner = LandData.OwnerID;
396 598
397 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 599 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
398 m_scene.EventManager.TriggerParcelPrimCountUpdate(); 600// m_scene.EventManager.TriggerParcelPrimCountUpdate();
399 SendLandUpdateToAvatarsOverMe(true); 601 SendLandUpdateToAvatarsOverMe(true);
400 602
401 if (sellObjects) SellLandObjects(previousOwner); 603 if (sellObjects) SellLandObjects(previousOwner);
@@ -431,7 +633,7 @@ namespace OpenSim.Region.CoreModules.World.Land
431 633
432 public bool CanBeOnThisLand(UUID avatar, float posHeight) 634 public bool CanBeOnThisLand(UUID avatar, float posHeight)
433 { 635 {
434 if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar)) 636 if (posHeight < LandChannel.BAN_LINE_SAFETY_HEIGHT && IsBannedFromLand(avatar))
435 { 637 {
436 return false; 638 return false;
437 } 639 }
@@ -530,7 +732,30 @@ namespace OpenSim.Region.CoreModules.World.Land
530 if (HasGroupAccess(avatar)) 732 if (HasGroupAccess(avatar))
531 return false; 733 return false;
532 734
533 return !IsInLandAccessList(avatar); 735 if(IsInLandAccessList(avatar))
736 return false;
737
738 // check for a NPC
739 ScenePresence sp;
740 if (!m_scene.TryGetScenePresence(avatar, out sp))
741 return true;
742
743 if(sp==null || !sp.IsNPC)
744 return true;
745
746 INPC npccli = (INPC)sp.ControllingClient;
747 if(npccli== null)
748 return true;
749
750 UUID owner = npccli.Owner;
751
752 if(owner == UUID.Zero)
753 return true;
754
755 if (owner == LandData.OwnerID)
756 return false;
757
758 return !IsInLandAccessList(owner);
534 } 759 }
535 760
536 public bool IsInLandAccessList(UUID avatar) 761 public bool IsInLandAccessList(UUID avatar)
@@ -568,6 +793,7 @@ namespace OpenSim.Region.CoreModules.World.Land
568 793
569 public void SendLandUpdateToAvatarsOverMe(bool snap_selection) 794 public void SendLandUpdateToAvatarsOverMe(bool snap_selection)
570 { 795 {
796 m_scene.EventManager.TriggerParcelPrimCountUpdate();
571 m_scene.ForEachRootScenePresence(delegate(ScenePresence avatar) 797 m_scene.ForEachRootScenePresence(delegate(ScenePresence avatar)
572 { 798 {
573 ILandObject over = null; 799 ILandObject over = null;
@@ -587,13 +813,13 @@ namespace OpenSim.Region.CoreModules.World.Land
587 { 813 {
588 if (over.LandData.LocalID == LandData.LocalID) 814 if (over.LandData.LocalID == LandData.LocalID)
589 { 815 {
590 if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && 816 if(m_scene.RegionInfo.RegionSettings.AllowDamage)
591 m_scene.RegionInfo.RegionSettings.AllowDamage)
592 avatar.Invulnerable = false; 817 avatar.Invulnerable = false;
593 else 818 else
594 avatar.Invulnerable = true; 819 avatar.Invulnerable = (over.LandData.Flags & (uint)ParcelFlags.AllowDamage) == 0;
595 820
596 SendLandUpdateToClient(snap_selection, avatar.ControllingClient); 821 SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
822 avatar.currentParcelUUID = LandData.GlobalID;
597 } 823 }
598 } 824 }
599 }); 825 });
@@ -630,13 +856,13 @@ namespace OpenSim.Region.CoreModules.World.Land
630 IClientAPI remote_client) 856 IClientAPI remote_client)
631 { 857 {
632 858
633 if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both) 859 if ((flags & (uint) AccessList.Access) != 0)
634 { 860 {
635 List<LandAccessEntry> accessEntries = CreateAccessListArrayByFlag(AccessList.Access); 861 List<LandAccessEntry> accessEntries = CreateAccessListArrayByFlag(AccessList.Access);
636 remote_client.SendLandAccessListData(accessEntries,(uint) AccessList.Access,LandData.LocalID); 862 remote_client.SendLandAccessListData(accessEntries,(uint) AccessList.Access,LandData.LocalID);
637 } 863 }
638 864
639 if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both) 865 if ((flags & (uint) AccessList.Ban) != 0)
640 { 866 {
641 List<LandAccessEntry> accessEntries = CreateAccessListArrayByFlag(AccessList.Ban); 867 List<LandAccessEntry> accessEntries = CreateAccessListArrayByFlag(AccessList.Ban);
642 remote_client.SendLandAccessListData(accessEntries, (uint)AccessList.Ban, LandData.LocalID); 868 remote_client.SendLandAccessListData(accessEntries, (uint)AccessList.Ban, LandData.LocalID);
@@ -691,6 +917,17 @@ namespace OpenSim.Region.CoreModules.World.Land
691 newData.ParcelAccessList.Add(temp); 917 newData.ParcelAccessList.Add(temp);
692 } 918 }
693 919
920 // update use lists flags
921 // rights already checked or we wont be here
922 uint parcelflags = newData.Flags;
923
924 if((flags & (uint)AccessList.Access) != 0)
925 parcelflags |= (uint)ParcelFlags.UseAccessList;
926 if((flags & (uint)AccessList.Ban) != 0)
927 parcelflags |= (uint)ParcelFlags.UseBanList;
928
929 newData.Flags = parcelflags;
930
694 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 931 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
695 } 932 }
696 933
@@ -708,7 +945,7 @@ namespace OpenSim.Region.CoreModules.World.Land
708 /// </summary> 945 /// </summary>
709 public void ForceUpdateLandInfo() 946 public void ForceUpdateLandInfo()
710 { 947 {
711 UpdateAABBAndAreaValues(); 948 UpdateGeometryValues();
712 UpdateLandBitmapByteArray(); 949 UpdateLandBitmapByteArray();
713 } 950 }
714 951
@@ -718,52 +955,117 @@ namespace OpenSim.Region.CoreModules.World.Land
718 } 955 }
719 956
720 /// <summary> 957 /// <summary>
721 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object 958 /// Updates geomtric values after area/shape modification of the land object
722 /// </summary> 959 /// </summary>
723 private void UpdateAABBAndAreaValues() 960 private void UpdateGeometryValues()
724 { 961 {
725 int min_x = 10000; 962 int min_x = Int32.MaxValue;
726 int min_y = 10000; 963 int min_y = Int32.MaxValue;
727 int max_x = 0; 964 int max_x = Int32.MinValue;
728 int max_y = 0; 965 int max_y = Int32.MinValue;
729 int tempArea = 0; 966 int tempArea = 0;
730 int x, y; 967 int x, y;
968
969 int lastX = 0;
970 int lastY = 0;
971 float avgx = 0f;
972 float avgy = 0f;
973
974 bool needFirst = true;
975
731 for (x = 0; x < LandBitmap.GetLength(0); x++) 976 for (x = 0; x < LandBitmap.GetLength(0); x++)
732 { 977 {
733 for (y = 0; y < LandBitmap.GetLength(1); y++) 978 for (y = 0; y < LandBitmap.GetLength(1); y++)
734 { 979 {
735 if (LandBitmap[x, y] == true) 980 if (LandBitmap[x, y])
736 { 981 {
737 if (min_x > x) min_x = x; 982 if (min_x > x)
738 if (min_y > y) min_y = y; 983 min_x = x;
739 if (max_x < x) max_x = x; 984 if (min_y > y)
740 if (max_y < y) max_y = y; 985 min_y = y;
741 tempArea += landUnit * landUnit; //16sqm peice of land 986 if (max_x < x)
987 max_x = x;
988 if (max_y < y)
989 max_y = y;
990
991 if(needFirst)
992 {
993 avgx = x;
994 avgy = y;
995 m_startPoint.X = x * landUnit;
996 m_startPoint.Y = y * landUnit;
997 needFirst = false;
998 }
999 else
1000 {
1001 // keeping previus odd average
1002 avgx = (avgx * tempArea + x) / (tempArea + 1);
1003 avgy = (avgy * tempArea + y) / (tempArea + 1);
1004 }
1005
1006 tempArea++;
1007
1008 lastX = x;
1009 lastY = y;
742 } 1010 }
743 } 1011 }
744 } 1012 }
1013
1014 int halfunit = landUnit/2;
1015
1016 m_centerPoint.X = avgx * landUnit + halfunit;
1017 m_centerPoint.Y = avgy * landUnit + halfunit;
1018
1019 m_endPoint.X = lastX * landUnit + landUnit;
1020 m_endPoint.Y = lastY * landUnit + landUnit;
1021
1022 // next tests should not be needed
1023 // if they fail, something is wrong
1024
1025 int regionSizeX = (int)Constants.RegionSize;
1026 int regionSizeY = (int)Constants.RegionSize;
1027
1028 if(m_scene != null)
1029 {
1030 regionSizeX = (int)m_scene.RegionInfo.RegionSizeX;
1031 regionSizeY = (int)m_scene.RegionInfo.RegionSizeX;
1032 }
1033
745 int tx = min_x * landUnit; 1034 int tx = min_x * landUnit;
746 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) 1035 if (tx >= regionSizeX)
747 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); 1036 tx = regionSizeX - 1;
1037
748 int ty = min_y * landUnit; 1038 int ty = min_y * landUnit;
749 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1)) 1039 if (ty >= regionSizeY)
750 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1); 1040 ty = regionSizeY - 1;
751 1041
752 LandData.AABBMin = 1042 m_AABBmin.X = tx;
753 new Vector3( 1043 m_AABBmin.Y = ty;
754 (float)(min_x * landUnit), (float)(min_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 1044
1045 if(m_scene == null || m_scene.Heightmap == null)
1046 LandData.AABBMin = new Vector3(tx, ty, 0f);
1047 else
1048 LandData.AABBMin = new Vector3(tx, ty, (float)m_scene.Heightmap[tx, ty]);
755 1049
1050 max_x++;
756 tx = max_x * landUnit; 1051 tx = max_x * landUnit;
757 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) 1052 if (tx > regionSizeX)
758 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); 1053 tx = regionSizeX;
1054
1055 max_y++;
759 ty = max_y * landUnit; 1056 ty = max_y * landUnit;
760 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1)) 1057 if (ty > regionSizeY)
761 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1); 1058 ty = regionSizeY;
1059
1060 m_AABBmax.X = tx;
1061 m_AABBmax.Y = ty;
762 1062
763 LandData.AABBMax 1063 if(m_scene == null || m_scene.Heightmap == null)
764 = new Vector3( 1064 LandData.AABBMax = new Vector3(tx, ty, 0f);
765 (float)(max_x * landUnit), (float)(max_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 1065 else
1066 LandData.AABBMax = new Vector3(tx, ty, (float)m_scene.Heightmap[tx - 1, ty - 1]);
766 1067
1068 tempArea *= landUnit * landUnit;
767 LandData.Area = tempArea; 1069 LandData.Area = tempArea;
768 } 1070 }
769 1071
@@ -778,7 +1080,6 @@ namespace OpenSim.Region.CoreModules.World.Land
778 public void SetLandBitmap(bool[,] bitmap) 1080 public void SetLandBitmap(bool[,] bitmap)
779 { 1081 {
780 LandBitmap = bitmap; 1082 LandBitmap = bitmap;
781 // m_log.DebugFormat("{0} SetLandBitmap. BitmapSize=<{1},{2}>", LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
782 ForceUpdateLandInfo(); 1083 ForceUpdateLandInfo();
783 } 1084 }
784 1085
@@ -793,17 +1094,17 @@ namespace OpenSim.Region.CoreModules.World.Land
793 1094
794 public bool[,] BasicFullRegionLandBitmap() 1095 public bool[,] BasicFullRegionLandBitmap()
795 { 1096 {
796 return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY); 1097 return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY, true);
797 } 1098 }
798 1099
799 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) 1100 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y, bool set_value = true)
800 { 1101 {
801 // Empty bitmap for the whole region 1102 // Empty bitmap for the whole region
802 bool[,] tempBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; 1103 bool[,] tempBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
803 tempBitmap.Initialize(); 1104 tempBitmap.Initialize();
804 1105
805 // Fill the bitmap square area specified by state and end 1106 // Fill the bitmap square area specified by state and end
806 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); 1107 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, set_value);
807 // m_log.DebugFormat("{0} GetSquareLandBitmap. tempBitmapSize=<{1},{2}>", 1108 // m_log.DebugFormat("{0} GetSquareLandBitmap. tempBitmapSize=<{1},{2}>",
808 // LogHeader, tempBitmap.GetLength(0), tempBitmap.GetLength(1)); 1109 // LogHeader, tempBitmap.GetLength(0), tempBitmap.GetLength(1));
809 return tempBitmap; 1110 return tempBitmap;
@@ -873,51 +1174,288 @@ namespace OpenSim.Region.CoreModules.World.Land
873 } 1174 }
874 1175
875 /// <summary> 1176 /// <summary>
1177 /// Remap a land bitmap. Takes the supplied land bitmap and rotates it, crops it and finally offsets it into
1178 /// a final land bitmap of the target region size.
1179 /// </summary>
1180 /// <param name="bitmap_base">The original parcel bitmap</param>
1181 /// <param name="rotationDegrees"></param>
1182 /// <param name="displacement">&lt;x,y,?&gt;</param>
1183 /// <param name="boundingOrigin">&lt;x,y,?&gt;</param>
1184 /// <param name="boundingSize">&lt;x,y,?&gt;</param>
1185 /// <param name="regionSize">&lt;x,y,?&gt;</param>
1186 /// <param name="isEmptyNow">out: This is set if the resultant bitmap is now empty</param>
1187 /// <param name="AABBMin">out: parcel.AABBMin &lt;x,y,0&gt</param>
1188 /// <param name="AABBMax">out: parcel.AABBMax &lt;x,y,0&gt</param>
1189 /// <returns>New parcel bitmap</returns>
1190 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)
1191 {
1192 // get the size of the incoming bitmap
1193 int baseX = bitmap_base.GetLength(0);
1194 int baseY = bitmap_base.GetLength(1);
1195
1196 // create an intermediate bitmap that is 25% bigger on each side that we can work with to handle rotations
1197 int offsetX = baseX / 4; // the original origin will now be at these coordinates so now we can have imaginary negative coordinates ;)
1198 int offsetY = baseY / 4;
1199 int tmpX = baseX + baseX / 2;
1200 int tmpY = baseY + baseY / 2;
1201 int centreX = tmpX / 2;
1202 int centreY = tmpY / 2;
1203 bool[,] bitmap_tmp = new bool[tmpX, tmpY];
1204
1205 double radianRotation = Math.PI * rotationDegrees / 180f;
1206 double cosR = Math.Cos(radianRotation);
1207 double sinR = Math.Sin(radianRotation);
1208 if (rotationDegrees < 0f) rotationDegrees += 360f; //-90=270 -180=180 -270=90
1209
1210 // So first we apply the rotation to the incoming bitmap, storing the result in bitmap_tmp
1211 // We special case orthogonal rotations for accuracy because even using double precision math, Math.Cos(90 degrees) is never fully 0
1212 // and we can never rotate around a centre pixel because the bitmap size is always even
1213 int x, y, sx, sy;
1214 for (y = 0; y <= tmpY; y++)
1215 {
1216 for (x = 0; x <= tmpX; x++)
1217 {
1218 if (rotationDegrees == 0f)
1219 {
1220 sx = x - offsetX;
1221 sy = y - offsetY;
1222 }
1223 else if (rotationDegrees == 90f)
1224 {
1225 sx = y - offsetX;
1226 sy = tmpY - 1 - x - offsetY;
1227 }
1228 else if (rotationDegrees == 180f)
1229 {
1230 sx = tmpX - 1 - x - offsetX;
1231 sy = tmpY - 1 - y - offsetY;
1232 }
1233 else if (rotationDegrees == 270f)
1234 {
1235 sx = tmpX - 1 - y - offsetX;
1236 sy = x - offsetY;
1237 }
1238 else
1239 {
1240 // arbitary rotation: hmmm should I be using (centreX - 0.5) and (centreY - 0.5) and round cosR and sinR to say only 5 decimal places?
1241 sx = centreX + (int)Math.Round((((double)x - centreX) * cosR) + (((double)y - centreY) * sinR)) - offsetX;
1242 sy = centreY + (int)Math.Round((((double)y - centreY) * cosR) - (((double)x - centreX) * sinR)) - offsetY;
1243 }
1244 if (sx >= 0 && sx < baseX && sy >= 0 && sy < baseY)
1245 {
1246 try
1247 {
1248 if (bitmap_base[sx, sy]) bitmap_tmp[x, y] = true;
1249 }
1250 catch (Exception) //just in case we've still not taken care of every way the arrays might go out of bounds! ;)
1251 {
1252 m_log.DebugFormat("{0} RemapLandBitmap Rotate: Out of Bounds sx={1} sy={2} dx={3} dy={4}", LogHeader, sx, sy, x, y);
1253 }
1254 }
1255 }
1256 }
1257
1258 // We could also incorporate the next steps, bounding-rectangle and displacement in the loop above, but it's simpler to visualise if done separately
1259 // and will also make it much easier when later I want the option for maybe a circular or oval bounding shape too ;).
1260 // So... our output land bitmap must be the size of the current region but rememeber, parcel landbitmaps are landUnit metres (4x4 metres) per point,
1261 // and region sizes, boundaries and displacements are in metres so we need to scale down
1262
1263 int newX = (int)(regionSize.X / landUnit);
1264 int newY = (int)(regionSize.Y / landUnit);
1265 bool[,] bitmap_new = new bool[newX, newY];
1266 // displacement is relative to <0,0> in the destination region and defines where the origin of the data selected by the bounding-rectangle is placed
1267 int dispX = (int)Math.Floor(displacement.X / landUnit);
1268 int dispY = (int)Math.Floor(displacement.Y / landUnit);
1269
1270 // startX/Y and endX/Y are coordinates in bitmap_tmp
1271 int startX = (int)Math.Floor(boundingOrigin.X / landUnit) + offsetX;
1272 if (startX > tmpX) startX = tmpX;
1273 if (startX < 0) startX = 0;
1274 int startY = (int)Math.Floor(boundingOrigin.Y / landUnit) + offsetY;
1275 if (startY > tmpY) startY = tmpY;
1276 if (startY < 0) startY = 0;
1277
1278 int endX = (int)Math.Floor((boundingOrigin.X + boundingSize.X) / landUnit) + offsetX;
1279 if (endX > tmpX) endX = tmpX;
1280 if (endX < 0) endX = 0;
1281 int endY = (int)Math.Floor((boundingOrigin.Y + boundingSize.Y) / landUnit) + offsetY;
1282 if (endY > tmpY) endY = tmpY;
1283 if (endY < 0) endY = 0;
1284
1285 //m_log.DebugFormat("{0} RemapLandBitmap: inSize=<{1},{2}>, disp=<{3},{4}> rot={5}, offset=<{6},{7}>, boundingStart=<{8},{9}>, boundingEnd=<{10},{11}>, cosR={12}, sinR={13}, outSize=<{14},{15}>", LogHeader,
1286 // baseX, baseY, dispX, dispY, radianRotation, offsetX, offsetY, startX, startY, endX, endY, cosR, sinR, newX, newY);
1287
1288 isEmptyNow = true;
1289 int minX = newX;
1290 int minY = newY;
1291 int maxX = 0;
1292 int maxY = 0;
1293
1294 int dx, dy;
1295 for (y = startY; y < endY; y++)
1296 {
1297 for (x = startX; x < endX; x++)
1298 {
1299 dx = x - startX + dispX;
1300 dy = y - startY + dispY;
1301 if (dx >= 0 && dx < newX && dy >= 0 && dy < newY)
1302 {
1303 try
1304 {
1305 if (bitmap_tmp[x, y])
1306 {
1307 bitmap_new[dx, dy] = true;
1308 isEmptyNow = false;
1309 if (dx < minX) minX = dx;
1310 if (dy < minY) minY = dy;
1311 if (dx > maxX) maxX = dx;
1312 if (dy > maxY) maxY = dy;
1313 }
1314 }
1315 catch (Exception) //just in case we've still not taken care of every way the arrays might go out of bounds! ;)
1316 {
1317 m_log.DebugFormat("{0} RemapLandBitmap - Bound & Displace: Out of Bounds sx={1} sy={2} dx={3} dy={4}", LogHeader, x, y, dx, dy);
1318 }
1319 }
1320 }
1321 }
1322 if (isEmptyNow)
1323 {
1324 //m_log.DebugFormat("{0} RemapLandBitmap: Land bitmap is marked as Empty", LogHeader);
1325 minX = 0;
1326 minY = 0;
1327 }
1328
1329 AABBMin = new Vector3(minX * landUnit, minY * landUnit, 0);
1330 AABBMax = new Vector3(maxX * landUnit, maxY * landUnit, 0);
1331 return bitmap_new;
1332 }
1333
1334 /// <summary>
1335 /// Clears any parcel data in bitmap_base where there exists parcel data in bitmap_new. In other words the parcel data
1336 /// in bitmap_new takes over the space of the parcel data in bitmap_base.
1337 /// </summary>
1338 /// <param name="bitmap_base"></param>
1339 /// <param name="bitmap_new"></param>
1340 /// <param name="isEmptyNow">out: This is set if the resultant bitmap is now empty</param>
1341 /// <param name="AABBMin">out: parcel.AABBMin &lt;x,y,0&gt</param>
1342 /// <param name="AABBMax">out: parcel.AABBMax &lt;x,y,0&gt</param>
1343 /// <returns>New parcel bitmap</returns>
1344 public bool[,] RemoveFromLandBitmap(bool[,] bitmap_base, bool[,] bitmap_new, out bool isEmptyNow, out Vector3 AABBMin, out Vector3 AABBMax)
1345 {
1346 // get the size of the incoming bitmaps
1347 int baseX = bitmap_base.GetLength(0);
1348 int baseY = bitmap_base.GetLength(1);
1349 int newX = bitmap_new.GetLength(0);
1350 int newY = bitmap_new.GetLength(1);
1351
1352 if (baseX != newX || baseY != newY)
1353 {
1354 throw new Exception(
1355 String.Format("{0} RemoveFromLandBitmap: Land bitmaps are not the same size! baseX={1} baseY={2} newX={3} newY={4}", LogHeader, baseX, baseY, newX, newY));
1356 }
1357
1358 isEmptyNow = true;
1359 int minX = baseX;
1360 int minY = baseY;
1361 int maxX = 0;
1362 int maxY = 0;
1363
1364 for (int y = 0; y < baseY; y++)
1365 {
1366 for (int x = 0; x < baseX; x++)
1367 {
1368 if (bitmap_new[x, y]) bitmap_base[x, y] = false;
1369 if (bitmap_base[x, y])
1370 {
1371 isEmptyNow = false;
1372 if (x < minX) minX = x;
1373 if (y < minY) minY = y;
1374 if (x > maxX) maxX = x;
1375 if (y > maxY) maxY = y;
1376 }
1377 }
1378 }
1379 if (isEmptyNow)
1380 {
1381 //m_log.DebugFormat("{0} RemoveFromLandBitmap: Land bitmap is marked as Empty", LogHeader);
1382 minX = 0;
1383 minY = 0;
1384 }
1385 AABBMin = new Vector3(minX * landUnit, minY * landUnit, 0);
1386 AABBMax = new Vector3(maxX * landUnit, maxY * landUnit, 0);
1387 return bitmap_base;
1388 }
1389
1390 /// <summary>
876 /// Converts the land bitmap to a packet friendly byte array 1391 /// Converts the land bitmap to a packet friendly byte array
877 /// </summary> 1392 /// </summary>
878 /// <returns></returns> 1393 /// <returns></returns>
879 private byte[] ConvertLandBitmapToBytes() 1394 public byte[] ConvertLandBitmapToBytes()
880 { 1395 {
881 byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8]; 1396 byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
882 byte tempByte = 0; 1397
883 int byteNum = 0; 1398 int tempByte = 0;
884 int i = 0; 1399 int i, byteNum = 0;
1400 int mask = 1;
1401 i = 0;
885 for (int y = 0; y < LandBitmap.GetLength(1); y++) 1402 for (int y = 0; y < LandBitmap.GetLength(1); y++)
886 { 1403 {
887 for (int x = 0; x < LandBitmap.GetLength(0); x++) 1404 for (int x = 0; x < LandBitmap.GetLength(0); x++)
888 { 1405 {
889 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); 1406 if (LandBitmap[x, y])
890 if (i % 8 == 0) 1407 tempByte |= mask;
1408 mask = mask << 1;
1409 if (mask == 0x100)
891 { 1410 {
892 tempConvertArr[byteNum] = tempByte; 1411 mask = 1;
893 tempByte = (byte) 0; 1412 tempConvertArr[byteNum++] = (byte)tempByte;
894 i = 0; 1413 tempByte = 0;
895 byteNum++;
896 } 1414 }
897 } 1415 }
898 } 1416 }
899 // m_log.DebugFormat("{0} ConvertLandBitmapToBytes. BitmapSize=<{1},{2}>", 1417
900 // LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); 1418 if(tempByte != 0 && byteNum < 512)
1419 tempConvertArr[byteNum] = (byte)tempByte;
1420
901 return tempConvertArr; 1421 return tempConvertArr;
902 } 1422 }
903 1423
904 private bool[,] ConvertBytesToLandBitmap() 1424 public bool[,] ConvertBytesToLandBitmap(bool overrideRegionSize = false)
905 { 1425 {
906 bool[,] tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; 1426 int bitmapLen;
907 tempConvertMap.Initialize(); 1427 int xLen;
908 byte tempByte = 0; 1428 bool[,] tempConvertMap;
909 // Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
910 int bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8);
911 int xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit);
912 1429
913 if (bitmapLen == 512) 1430 if (overrideRegionSize)
1431 {
1432 // Importing land parcel data from an OAR where the source region is a different size to the dest region requires us
1433 // to make a LandBitmap that's not derived from the current region's size. We use the LandData.Bitmap size in bytes
1434 // to figure out what the OAR's region dimensions are. (Is there a better way to get the src region x and y from the OAR?)
1435 // This method assumes we always will have square regions
1436
1437 bitmapLen = LandData.Bitmap.Length;
1438 xLen = (int)Math.Abs(Math.Sqrt(bitmapLen * 8));
1439 tempConvertMap = new bool[xLen, xLen];
1440 tempConvertMap.Initialize();
1441 }
1442 else
914 { 1443 {
915 // Legacy bitmap being passed in. Use the legacy region size 1444 tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
916 // and only set the lower area of the larger region. 1445 tempConvertMap.Initialize();
917 xLen = (int)(Constants.RegionSize / landUnit); 1446 // Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
1447 bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8);
1448 xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit);
1449 if (bitmapLen == 512)
1450 {
1451 // Legacy bitmap being passed in. Use the legacy region size
1452 // and only set the lower area of the larger region.
1453 xLen = (int)(Constants.RegionSize / landUnit);
1454 }
918 } 1455 }
919 // m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen); 1456 // m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen);
920 1457
1458 byte tempByte;
921 int x = 0, y = 0; 1459 int x = 0, y = 0;
922 for (int i = 0; i < bitmapLen; i++) 1460 for (int i = 0; i < bitmapLen; i++)
923 { 1461 {
@@ -945,13 +1483,39 @@ namespace OpenSim.Region.CoreModules.World.Land
945 return tempConvertMap; 1483 return tempConvertMap;
946 } 1484 }
947 1485
1486 public bool IsLandBitmapEmpty(bool[,] landBitmap)
1487 {
1488 for (int y = 0; y < landBitmap.GetLength(1); y++)
1489 {
1490 for (int x = 0; x < landBitmap.GetLength(0); x++)
1491 {
1492 if (landBitmap[x, y]) return false;
1493 }
1494 }
1495 return true;
1496 }
1497
1498 public void DebugLandBitmap(bool[,] landBitmap)
1499 {
1500 m_log.InfoFormat("{0}: Map Key: #=claimed land .=unclaimed land.", LogHeader);
1501 for (int y = landBitmap.GetLength(1) - 1; y >= 0; y--)
1502 {
1503 string row = "";
1504 for (int x = 0; x < landBitmap.GetLength(0); x++)
1505 {
1506 row += landBitmap[x, y] ? "#" : ".";
1507 }
1508 m_log.InfoFormat("{0}: {1}", LogHeader, row);
1509 }
1510 }
1511
948 #endregion 1512 #endregion
949 1513
950 #region Object Select and Object Owner Listing 1514 #region Object Select and Object Owner Listing
951 1515
952 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client) 1516 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client)
953 { 1517 {
954 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) 1518 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
955 { 1519 {
956 List<uint> resultLocalIDs = new List<uint>(); 1520 List<uint> resultLocalIDs = new List<uint>();
957 try 1521 try
@@ -1001,7 +1565,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1001 /// </param> 1565 /// </param>
1002 public void SendLandObjectOwners(IClientAPI remote_client) 1566 public void SendLandObjectOwners(IClientAPI remote_client)
1003 { 1567 {
1004 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) 1568 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
1005 { 1569 {
1006 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>(); 1570 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>();
1007 List<UUID> groups = new List<UUID>(); 1571 List<UUID> groups = new List<UUID>();
@@ -1009,9 +1573,9 @@ namespace OpenSim.Region.CoreModules.World.Land
1009 lock (primsOverMe) 1573 lock (primsOverMe)
1010 { 1574 {
1011// m_log.DebugFormat( 1575// m_log.DebugFormat(
1012// "[LAND OBJECT]: Request for SendLandObjectOwners() from {0} with {1} known prims on region", 1576// "[LAND OBJECT]: Request for SendLandObjectOwners() from {0} with {1} known prims on region",
1013// remote_client.Name, primsOverMe.Count); 1577// remote_client.Name, primsOverMe.Count);
1014 1578
1015 try 1579 try
1016 { 1580 {
1017 foreach (SceneObjectGroup obj in primsOverMe) 1581 foreach (SceneObjectGroup obj in primsOverMe)
@@ -1052,7 +1616,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1052 public Dictionary<UUID, int> GetLandObjectOwners() 1616 public Dictionary<UUID, int> GetLandObjectOwners()
1053 { 1617 {
1054 Dictionary<UUID, int> ownersAndCount = new Dictionary<UUID, int>(); 1618 Dictionary<UUID, int> ownersAndCount = new Dictionary<UUID, int>();
1055 1619
1056 lock (primsOverMe) 1620 lock (primsOverMe)
1057 { 1621 {
1058 try 1622 try
@@ -1106,8 +1670,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1106 { 1670 {
1107 foreach (SceneObjectGroup obj in primsOverMe) 1671 foreach (SceneObjectGroup obj in primsOverMe)
1108 { 1672 {
1109 if (obj.OwnerID == previousOwner && obj.GroupID == UUID.Zero && 1673 if(m_scene.Permissions.CanSellObject(previousOwner,obj, (byte)SaleType.Original))
1110 (obj.GetEffectivePermissions() & (uint)(OpenSim.Framework.PermissionMask.Transfer)) != 0)
1111 m_BuySellModule.BuyObject(sp.ControllingClient, UUID.Zero, obj.LocalId, 1, 0); 1674 m_BuySellModule.BuyObject(sp.ControllingClient, UUID.Zero, obj.LocalId, 1, 0);
1112 } 1675 }
1113 } 1676 }
@@ -1121,14 +1684,14 @@ namespace OpenSim.Region.CoreModules.World.Land
1121 { 1684 {
1122 SceneObjectGroup[] objs = new SceneObjectGroup[1]; 1685 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1123 objs[0] = obj; 1686 objs[0] = obj;
1124 m_scene.returnObjects(objs, obj.OwnerID); 1687 m_scene.returnObjects(objs, null);
1125 } 1688 }
1126 1689
1127 public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) 1690 public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client)
1128 { 1691 {
1129// m_log.DebugFormat( 1692// m_log.DebugFormat(
1130// "[LAND OBJECT]: Request to return objects in {0} from {1}", LandData.Name, remote_client.Name); 1693// "[LAND OBJECT]: Request to return objects in {0} from {1}", LandData.Name, remote_client.Name);
1131 1694
1132 Dictionary<UUID,List<SceneObjectGroup>> returns = new Dictionary<UUID,List<SceneObjectGroup>>(); 1695 Dictionary<UUID,List<SceneObjectGroup>> returns = new Dictionary<UUID,List<SceneObjectGroup>>();
1133 1696
1134 lock (primsOverMe) 1697 lock (primsOverMe)
@@ -1152,6 +1715,8 @@ namespace OpenSim.Region.CoreModules.World.Land
1152 { 1715 {
1153 if (obj.GroupID == LandData.GroupID) 1716 if (obj.GroupID == LandData.GroupID)
1154 { 1717 {
1718 if (obj.OwnerID == LandData.OwnerID)
1719 continue;
1155 if (!returns.ContainsKey(obj.OwnerID)) 1720 if (!returns.ContainsKey(obj.OwnerID))
1156 returns[obj.OwnerID] = 1721 returns[obj.OwnerID] =
1157 new List<SceneObjectGroup>(); 1722 new List<SceneObjectGroup>();
@@ -1193,8 +1758,8 @@ namespace OpenSim.Region.CoreModules.World.Land
1193 1758
1194 foreach (List<SceneObjectGroup> ol in returns.Values) 1759 foreach (List<SceneObjectGroup> ol in returns.Values)
1195 { 1760 {
1196 if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) 1761 if (m_scene.Permissions.CanReturnObjects(this, remote_client, ol))
1197 m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); 1762 m_scene.returnObjects(ol.ToArray(), remote_client);
1198 } 1763 }
1199 } 1764 }
1200 1765
@@ -1211,7 +1776,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1211 public void AddPrimOverMe(SceneObjectGroup obj) 1776 public void AddPrimOverMe(SceneObjectGroup obj)
1212 { 1777 {
1213// m_log.DebugFormat("[LAND OBJECT]: Adding scene object {0} {1} over {2}", obj.Name, obj.LocalId, LandData.Name); 1778// m_log.DebugFormat("[LAND OBJECT]: Adding scene object {0} {1} over {2}", obj.Name, obj.LocalId, LandData.Name);
1214 1779
1215 lock (primsOverMe) 1780 lock (primsOverMe)
1216 primsOverMe.Add(obj); 1781 primsOverMe.Add(obj);
1217 } 1782 }
@@ -1219,13 +1784,13 @@ namespace OpenSim.Region.CoreModules.World.Land
1219 public void RemovePrimFromOverMe(SceneObjectGroup obj) 1784 public void RemovePrimFromOverMe(SceneObjectGroup obj)
1220 { 1785 {
1221// m_log.DebugFormat("[LAND OBJECT]: Removing scene object {0} {1} from over {2}", obj.Name, obj.LocalId, LandData.Name); 1786// m_log.DebugFormat("[LAND OBJECT]: Removing scene object {0} {1} from over {2}", obj.Name, obj.LocalId, LandData.Name);
1222 1787
1223 lock (primsOverMe) 1788 lock (primsOverMe)
1224 primsOverMe.Remove(obj); 1789 primsOverMe.Remove(obj);
1225 } 1790 }
1226 1791
1227 #endregion 1792 #endregion
1228 1793
1229 /// <summary> 1794 /// <summary>
1230 /// Set the media url for this land parcel 1795 /// Set the media url for this land parcel
1231 /// </summary> 1796 /// </summary>
@@ -1233,9 +1798,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1233 public void SetMediaUrl(string url) 1798 public void SetMediaUrl(string url)
1234 { 1799 {
1235 LandData.MediaURL = url; 1800 LandData.MediaURL = url;
1801 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData);
1236 SendLandUpdateToAvatarsOverMe(); 1802 SendLandUpdateToAvatarsOverMe();
1237 } 1803 }
1238 1804
1239 /// <summary> 1805 /// <summary>
1240 /// Set the music url for this land parcel 1806 /// Set the music url for this land parcel
1241 /// </summary> 1807 /// </summary>
@@ -1243,6 +1809,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1243 public void SetMusicUrl(string url) 1809 public void SetMusicUrl(string url)
1244 { 1810 {
1245 LandData.MusicURL = url; 1811 LandData.MusicURL = url;
1812 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData);
1246 SendLandUpdateToAvatarsOverMe(); 1813 SendLandUpdateToAvatarsOverMe();
1247 } 1814 }
1248 1815
@@ -1257,6 +1824,48 @@ namespace OpenSim.Region.CoreModules.World.Land
1257 1824
1258 #endregion 1825 #endregion
1259 1826
1827 private void OnFrame()
1828 {
1829 m_expiryCounter++;
1830
1831 if (m_expiryCounter >= 50)
1832 {
1833 ExpireAccessList();
1834 m_expiryCounter = 0;
1835 }
1836
1837 // need to update dwell here bc landdata has no parent info
1838 if(LandData != null && m_dwellModule != null)
1839 {
1840 double now = Util.GetTimeStampMS();
1841 double elapsed = now - LandData.LastDwellTimeMS;
1842 if(elapsed > 150000) //2.5 minutes resolution / throttle
1843 {
1844 float dwell = LandData.Dwell;
1845 double cur = dwell * 60000.0;
1846 double decay = 1.5e-8 * cur * elapsed;
1847 cur -= decay;
1848 if(cur < 0)
1849 cur = 0;
1850
1851 UUID lgid = LandData.GlobalID;
1852 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1853 {
1854 if(sp.IsNPC || sp.IsLoggingIn || sp.IsDeleted || sp.currentParcelUUID != lgid)
1855 return;
1856 cur += (now - sp.ParcelDwellTickMS);
1857 sp.ParcelDwellTickMS = now;
1858 });
1859
1860 float newdwell = (float)(cur * 1.666666666667e-5);
1861 LandData.Dwell = newdwell;
1862
1863 if(Math.Abs(newdwell - dwell) >= 0.9)
1864 m_scene.EventManager.TriggerLandObjectAdded(this);
1865 }
1866 }
1867 }
1868
1260 private void ExpireAccessList() 1869 private void ExpireAccessList()
1261 { 1870 {
1262 List<LandAccessEntry> delete = new List<LandAccessEntry>(); 1871 List<LandAccessEntry> delete = new List<LandAccessEntry>();
@@ -1267,7 +1876,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1267 delete.Add(entry); 1876 delete.Add(entry);
1268 } 1877 }
1269 foreach (LandAccessEntry entry in delete) 1878 foreach (LandAccessEntry entry in delete)
1879 {
1270 LandData.ParcelAccessList.Remove(entry); 1880 LandData.ParcelAccessList.Remove(entry);
1881 ScenePresence presence;
1882
1883 if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
1884 {
1885 ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
1886 if (land.LandData.LocalID == LandData.LocalID)
1887 {
1888 Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
1889 presence.TeleportOnEject(pos);
1890 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
1891 }
1892 }
1893 m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
1894 }
1271 1895
1272 if (delete.Count > 0) 1896 if (delete.Count > 0)
1273 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); 1897 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this);
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index 9b51cc8..2a720db 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -69,11 +69,11 @@ namespace OpenSim.Region.CoreModules.World.Land
69 /// For now, a simple simwide taint to get this up. Later parcel based 69 /// For now, a simple simwide taint to get this up. Later parcel based
70 /// taint to allow recounting a parcel if only ownership has changed 70 /// taint to allow recounting a parcel if only ownership has changed
71 /// without recounting the whole sim. 71 /// without recounting the whole sim.
72 /// 72 ///
73 /// We start out tainted so that the first get call resets the various prim counts. 73 /// We start out tainted so that the first get call resets the various prim counts.
74 /// </value> 74 /// </value>
75 private bool m_Tainted = true; 75 private bool m_Tainted = true;
76 76
77 private Object m_TaintLock = new Object(); 77 private Object m_TaintLock = new Object();
78 78
79 public Type ReplaceableInterface 79 public Type ReplaceableInterface
@@ -88,14 +88,12 @@ namespace OpenSim.Region.CoreModules.World.Land
88 public void AddRegion(Scene scene) 88 public void AddRegion(Scene scene)
89 { 89 {
90 m_Scene = scene; 90 m_Scene = scene;
91 91
92 m_Scene.RegisterModuleInterface<IPrimCountModule>(this); 92 m_Scene.RegisterModuleInterface<IPrimCountModule>(this);
93 93
94 m_Scene.EventManager.OnObjectAddedToScene += OnParcelPrimCountAdd; 94 m_Scene.EventManager.OnObjectAddedToScene += OnParcelPrimCountAdd;
95 m_Scene.EventManager.OnObjectBeingRemovedFromScene += 95 m_Scene.EventManager.OnObjectBeingRemovedFromScene += OnObjectBeingRemovedFromScene;
96 OnObjectBeingRemovedFromScene; 96 m_Scene.EventManager.OnParcelPrimCountTainted += OnParcelPrimCountTainted;
97 m_Scene.EventManager.OnParcelPrimCountTainted +=
98 OnParcelPrimCountTainted;
99 m_Scene.EventManager.OnLandObjectAdded += delegate(ILandObject lo) { OnParcelPrimCountTainted(); }; 97 m_Scene.EventManager.OnLandObjectAdded += delegate(ILandObject lo) { OnParcelPrimCountTainted(); };
100 } 98 }
101 99
@@ -104,7 +102,7 @@ namespace OpenSim.Region.CoreModules.World.Land
104 } 102 }
105 103
106 public void RemoveRegion(Scene scene) 104 public void RemoveRegion(Scene scene)
107 { 105 {
108 } 106 }
109 107
110 public void Close() 108 public void Close()
@@ -126,7 +124,7 @@ namespace OpenSim.Region.CoreModules.World.Land
126 AddObject(obj); 124 AddObject(obj);
127// else 125// else
128// m_log.DebugFormat( 126// m_log.DebugFormat(
129// "[PRIM COUNT MODULE]: Ignoring OnParcelPrimCountAdd() for {0} on {1} since count is tainted", 127// "[PRIM COUNT MODULE]: Ignoring OnParcelPrimCountAdd() for {0} on {1} since count is tainted",
130// obj.Name, m_Scene.RegionInfo.RegionName); 128// obj.Name, m_Scene.RegionInfo.RegionName);
131 } 129 }
132 } 130 }
@@ -140,16 +138,16 @@ namespace OpenSim.Region.CoreModules.World.Land
140 RemoveObject(obj); 138 RemoveObject(obj);
141// else 139// else
142// m_log.DebugFormat( 140// m_log.DebugFormat(
143// "[PRIM COUNT MODULE]: Ignoring OnObjectBeingRemovedFromScene() for {0} on {1} since count is tainted", 141// "[PRIM COUNT MODULE]: Ignoring OnObjectBeingRemovedFromScene() for {0} on {1} since count is tainted",
144// obj.Name, m_Scene.RegionInfo.RegionName); 142// obj.Name, m_Scene.RegionInfo.RegionName);
145 } 143 }
146 } 144 }
147 145
148 private void OnParcelPrimCountTainted() 146 private void OnParcelPrimCountTainted()
149 { 147 {
150// m_log.DebugFormat( 148// m_log.DebugFormat(
151// "[PRIM COUNT MODULE]: OnParcelPrimCountTainted() called on {0}", m_Scene.RegionInfo.RegionName); 149// "[PRIM COUNT MODULE]: OnParcelPrimCountTainted() called on {0}", m_Scene.RegionInfo.RegionName);
152 150
153 lock (m_TaintLock) 151 lock (m_TaintLock)
154 m_Tainted = true; 152 m_Tainted = true;
155 } 153 }
@@ -174,40 +172,40 @@ namespace OpenSim.Region.CoreModules.World.Land
174 172
175 // NOTE: Call under Taint Lock 173 // NOTE: Call under Taint Lock
176 private void AddObject(SceneObjectGroup obj) 174 private void AddObject(SceneObjectGroup obj)
177 { 175 {
178 if (obj.IsAttachment) 176 if (obj.IsAttachment)
179 return; 177 return;
180 if (((obj.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)) 178 if (((obj.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0))
181 return; 179 return;
182 180
183 Vector3 pos = obj.AbsolutePosition; 181 Vector3 pos = obj.AbsolutePosition;
184 ILandObject landObject = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y); 182 ILandObject landObject = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
185 183
186 // If for some reason there is no land object (perhaps the object is out of bounds) then we can't count it 184 // If for some reason there is no land object (perhaps the object is out of bounds) then we can't count it
187 if (landObject == null) 185 if (landObject == null)
188 { 186 {
189// m_log.WarnFormat( 187// m_log.WarnFormat(
190// "[PRIM COUNT MODULE]: Found no land object for {0} at position ({1}, {2}) on {3}", 188// "[PRIM COUNT MODULE]: Found no land object for {0} at position ({1}, {2}) on {3}",
191// obj.Name, pos.X, pos.Y, m_Scene.RegionInfo.RegionName); 189// obj.Name, pos.X, pos.Y, m_Scene.RegionInfo.RegionName);
192 190
193 return; 191 return;
194 } 192 }
195 193
196 LandData landData = landObject.LandData; 194 LandData landData = landObject.LandData;
197 195
198// m_log.DebugFormat( 196// m_log.DebugFormat(
199// "[PRIM COUNT MODULE]: Adding object {0} with {1} parts to prim count for parcel {2} on {3}", 197// "[PRIM COUNT MODULE]: Adding object {0} with {1} parts to prim count for parcel {2} on {3}",
200// obj.Name, obj.Parts.Length, landData.Name, m_Scene.RegionInfo.RegionName); 198// obj.Name, obj.Parts.Length, landData.Name, m_Scene.RegionInfo.RegionName);
201 199
202// m_log.DebugFormat( 200// m_log.DebugFormat(
203// "[PRIM COUNT MODULE]: Object {0} is owned by {1} over land owned by {2}", 201// "[PRIM COUNT MODULE]: Object {0} is owned by {1} over land owned by {2}",
204// obj.Name, obj.OwnerID, landData.OwnerID); 202// obj.Name, obj.OwnerID, landData.OwnerID);
205 203
206 ParcelCounts parcelCounts; 204 ParcelCounts parcelCounts;
207 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) 205 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts))
208 { 206 {
209 UUID landOwner = landData.OwnerID; 207 UUID landOwner = landData.OwnerID;
210 int partCount = obj.Parts.Length; 208 int partCount = obj.GetPartCount();
211 209
212 m_SimwideCounts[landOwner] += partCount; 210 m_SimwideCounts[landOwner] += partCount;
213 if (parcelCounts.Users.ContainsKey(obj.OwnerID)) 211 if (parcelCounts.Users.ContainsKey(obj.OwnerID))
@@ -215,37 +213,23 @@ namespace OpenSim.Region.CoreModules.World.Land
215 else 213 else
216 parcelCounts.Users[obj.OwnerID] = partCount; 214 parcelCounts.Users[obj.OwnerID] = partCount;
217 215
218 if (obj.IsSelected) 216 if (obj.IsSelected || obj.GetSittingAvatarsCount() > 0)
219 { 217 parcelCounts.Selected += partCount;
220 parcelCounts.Selected += partCount; 218
221 } 219 if (obj.OwnerID == landData.OwnerID)
220 parcelCounts.Owner += partCount;
221 else if (landData.GroupID != UUID.Zero && obj.GroupID == landData.GroupID)
222 parcelCounts.Group += partCount;
222 else 223 else
223 { 224 parcelCounts.Others += partCount;
224 if (landData.IsGroupOwned)
225 {
226 if (obj.OwnerID == landData.GroupID)
227 parcelCounts.Owner += partCount;
228 else if (landData.GroupID != UUID.Zero && obj.GroupID == landData.GroupID)
229 parcelCounts.Group += partCount;
230 else
231 parcelCounts.Others += partCount;
232 }
233 else
234 {
235 if (obj.OwnerID == landData.OwnerID)
236 parcelCounts.Owner += partCount;
237 else
238 parcelCounts.Others += partCount;
239 }
240 }
241 } 225 }
242 } 226 }
243 227
244 // NOTE: Call under Taint Lock 228 // NOTE: Call under Taint Lock
245 private void RemoveObject(SceneObjectGroup obj) 229 private void RemoveObject(SceneObjectGroup obj)
246 { 230 {
247// m_log.DebugFormat("[PRIM COUNT MODULE]: Removing object {0} {1} from prim count", obj.Name, obj.UUID); 231// m_log.DebugFormat("[PRIM COUNT MODULE]: Removing object {0} {1} from prim count", obj.Name, obj.UUID);
248 232
249 // Currently this is being done by tainting the count instead. 233 // Currently this is being done by tainting the count instead.
250 } 234 }
251 235
@@ -253,7 +237,7 @@ namespace OpenSim.Region.CoreModules.World.Land
253 { 237 {
254// m_log.DebugFormat( 238// m_log.DebugFormat(
255// "[PRIM COUNT MODULE]: GetPrimCounts for parcel {0} in {1}", parcelID, m_Scene.RegionInfo.RegionName); 239// "[PRIM COUNT MODULE]: GetPrimCounts for parcel {0} in {1}", parcelID, m_Scene.RegionInfo.RegionName);
256 240
257 PrimCounts primCounts; 241 PrimCounts primCounts;
258 242
259 lock (m_PrimCounts) 243 lock (m_PrimCounts)
@@ -267,7 +251,7 @@ namespace OpenSim.Region.CoreModules.World.Land
267 return primCounts; 251 return primCounts;
268 } 252 }
269 253
270 254
271 /// <summary> 255 /// <summary>
272 /// Get the number of prims on the parcel that are owned by the parcel owner. 256 /// Get the number of prims on the parcel that are owned by the parcel owner.
273 /// </summary> 257 /// </summary>
@@ -276,7 +260,7 @@ namespace OpenSim.Region.CoreModules.World.Land
276 public int GetOwnerCount(UUID parcelID) 260 public int GetOwnerCount(UUID parcelID)
277 { 261 {
278 int count = 0; 262 int count = 0;
279 263
280 lock (m_TaintLock) 264 lock (m_TaintLock)
281 { 265 {
282 if (m_Tainted) 266 if (m_Tainted)
@@ -286,11 +270,11 @@ namespace OpenSim.Region.CoreModules.World.Land
286 if (m_ParcelCounts.TryGetValue(parcelID, out counts)) 270 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
287 count = counts.Owner; 271 count = counts.Owner;
288 } 272 }
289 273
290// m_log.DebugFormat( 274// m_log.DebugFormat(
291// "[PRIM COUNT MODULE]: GetOwnerCount for parcel {0} in {1} returning {2}", 275// "[PRIM COUNT MODULE]: GetOwnerCount for parcel {0} in {1} returning {2}",
292// parcelID, m_Scene.RegionInfo.RegionName, count); 276// parcelID, m_Scene.RegionInfo.RegionName, count);
293 277
294 return count; 278 return count;
295 } 279 }
296 280
@@ -298,11 +282,11 @@ namespace OpenSim.Region.CoreModules.World.Land
298 /// Get the number of prims on the parcel that have been set to the group that owns the parcel. 282 /// Get the number of prims on the parcel that have been set to the group that owns the parcel.
299 /// </summary> 283 /// </summary>
300 /// <param name="parcelID"></param> 284 /// <param name="parcelID"></param>
301 /// <returns></returns> 285 /// <returns></returns>
302 public int GetGroupCount(UUID parcelID) 286 public int GetGroupCount(UUID parcelID)
303 { 287 {
304 int count = 0; 288 int count = 0;
305 289
306 lock (m_TaintLock) 290 lock (m_TaintLock)
307 { 291 {
308 if (m_Tainted) 292 if (m_Tainted)
@@ -312,11 +296,11 @@ namespace OpenSim.Region.CoreModules.World.Land
312 if (m_ParcelCounts.TryGetValue(parcelID, out counts)) 296 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
313 count = counts.Group; 297 count = counts.Group;
314 } 298 }
315 299
316// m_log.DebugFormat( 300// m_log.DebugFormat(
317// "[PRIM COUNT MODULE]: GetGroupCount for parcel {0} in {1} returning {2}", 301// "[PRIM COUNT MODULE]: GetGroupCount for parcel {0} in {1} returning {2}",
318// parcelID, m_Scene.RegionInfo.RegionName, count); 302// parcelID, m_Scene.RegionInfo.RegionName, count);
319 303
320 return count; 304 return count;
321 } 305 }
322 306
@@ -324,11 +308,11 @@ namespace OpenSim.Region.CoreModules.World.Land
324 /// Get the number of prims on the parcel that are not owned by the parcel owner or set to the parcel group. 308 /// Get the number of prims on the parcel that are not owned by the parcel owner or set to the parcel group.
325 /// </summary> 309 /// </summary>
326 /// <param name="parcelID"></param> 310 /// <param name="parcelID"></param>
327 /// <returns></returns> 311 /// <returns></returns>
328 public int GetOthersCount(UUID parcelID) 312 public int GetOthersCount(UUID parcelID)
329 { 313 {
330 int count = 0; 314 int count = 0;
331 315
332 lock (m_TaintLock) 316 lock (m_TaintLock)
333 { 317 {
334 if (m_Tainted) 318 if (m_Tainted)
@@ -338,23 +322,23 @@ namespace OpenSim.Region.CoreModules.World.Land
338 if (m_ParcelCounts.TryGetValue(parcelID, out counts)) 322 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
339 count = counts.Others; 323 count = counts.Others;
340 } 324 }
341 325
342// m_log.DebugFormat( 326// m_log.DebugFormat(
343// "[PRIM COUNT MODULE]: GetOthersCount for parcel {0} in {1} returning {2}", 327// "[PRIM COUNT MODULE]: GetOthersCount for parcel {0} in {1} returning {2}",
344// parcelID, m_Scene.RegionInfo.RegionName, count); 328// parcelID, m_Scene.RegionInfo.RegionName, count);
345 329
346 return count; 330 return count;
347 } 331 }
348 332
349 /// <summary> 333 /// <summary>
350 /// Get the number of selected prims. 334 /// Get the number of selected prims.
351 /// </summary> 335 /// </summary>
352 /// <param name="parcelID"></param> 336 /// <param name="parcelID"></param>
353 /// <returns></returns> 337 /// <returns></returns>
354 public int GetSelectedCount(UUID parcelID) 338 public int GetSelectedCount(UUID parcelID)
355 { 339 {
356 int count = 0; 340 int count = 0;
357 341
358 lock (m_TaintLock) 342 lock (m_TaintLock)
359 { 343 {
360 if (m_Tainted) 344 if (m_Tainted)
@@ -364,24 +348,24 @@ namespace OpenSim.Region.CoreModules.World.Land
364 if (m_ParcelCounts.TryGetValue(parcelID, out counts)) 348 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
365 count = counts.Selected; 349 count = counts.Selected;
366 } 350 }
367 351
368// m_log.DebugFormat( 352// m_log.DebugFormat(
369// "[PRIM COUNT MODULE]: GetSelectedCount for parcel {0} in {1} returning {2}", 353// "[PRIM COUNT MODULE]: GetSelectedCount for parcel {0} in {1} returning {2}",
370// parcelID, m_Scene.RegionInfo.RegionName, count); 354// parcelID, m_Scene.RegionInfo.RegionName, count);
371 355
372 return count; 356 return count;
373 } 357 }
374 358
375 /// <summary> 359 /// <summary>
376 /// Get the total count of owner, group and others prims on the parcel. 360 /// Get the total count of owner, group and others prims on the parcel.
377 /// FIXME: Need to do selected prims once this is reimplemented. 361 /// FIXME: Need to do selected prims once this is reimplemented.
378 /// </summary> 362 /// </summary>
379 /// <param name="parcelID"></param> 363 /// <param name="parcelID"></param>
380 /// <returns></returns> 364 /// <returns></returns>
381 public int GetTotalCount(UUID parcelID) 365 public int GetTotalCount(UUID parcelID)
382 { 366 {
383 int count = 0; 367 int count = 0;
384 368
385 lock (m_TaintLock) 369 lock (m_TaintLock)
386 { 370 {
387 if (m_Tainted) 371 if (m_Tainted)
@@ -393,31 +377,30 @@ namespace OpenSim.Region.CoreModules.World.Land
393 count = counts.Owner; 377 count = counts.Owner;
394 count += counts.Group; 378 count += counts.Group;
395 count += counts.Others; 379 count += counts.Others;
396 count += counts.Selected;
397 } 380 }
398 } 381 }
399 382
400// m_log.DebugFormat( 383// m_log.DebugFormat(
401// "[PRIM COUNT MODULE]: GetTotalCount for parcel {0} in {1} returning {2}", 384// "[PRIM COUNT MODULE]: GetTotalCount for parcel {0} in {1} returning {2}",
402// parcelID, m_Scene.RegionInfo.RegionName, count); 385// parcelID, m_Scene.RegionInfo.RegionName, count);
403 386
404 return count; 387 return count;
405 } 388 }
406 389
407 /// <summary> 390 /// <summary>
408 /// Get the number of prims that are in the entire simulator for the owner of this parcel. 391 /// Get the number of prims that are in the entire simulator for the owner of this parcel.
409 /// </summary> 392 /// </summary>
410 /// <param name="parcelID"></param> 393 /// <param name="parcelID"></param>
411 /// <returns></returns> 394 /// <returns></returns>
412 public int GetSimulatorCount(UUID parcelID) 395 public int GetSimulatorCount(UUID parcelID)
413 { 396 {
414 int count = 0; 397 int count = 0;
415 398
416 lock (m_TaintLock) 399 lock (m_TaintLock)
417 { 400 {
418 if (m_Tainted) 401 if (m_Tainted)
419 Recount(); 402 Recount();
420 403
421 UUID owner; 404 UUID owner;
422 if (m_OwnerMap.TryGetValue(parcelID, out owner)) 405 if (m_OwnerMap.TryGetValue(parcelID, out owner))
423 { 406 {
@@ -426,11 +409,11 @@ namespace OpenSim.Region.CoreModules.World.Land
426 count = val; 409 count = val;
427 } 410 }
428 } 411 }
429 412
430// m_log.DebugFormat( 413// m_log.DebugFormat(
431// "[PRIM COUNT MODULE]: GetOthersCount for parcel {0} in {1} returning {2}", 414// "[PRIM COUNT MODULE]: GetOthersCount for parcel {0} in {1} returning {2}",
432// parcelID, m_Scene.RegionInfo.RegionName, count); 415// parcelID, m_Scene.RegionInfo.RegionName, count);
433 416
434 return count; 417 return count;
435 } 418 }
436 419
@@ -439,11 +422,11 @@ namespace OpenSim.Region.CoreModules.World.Land
439 /// </summary> 422 /// </summary>
440 /// <param name="parcelID"></param> 423 /// <param name="parcelID"></param>
441 /// <param name="userID"></param> 424 /// <param name="userID"></param>
442 /// <returns></returns> 425 /// <returns></returns>
443 public int GetUserCount(UUID parcelID, UUID userID) 426 public int GetUserCount(UUID parcelID, UUID userID)
444 { 427 {
445 int count = 0; 428 int count = 0;
446 429
447 lock (m_TaintLock) 430 lock (m_TaintLock)
448 { 431 {
449 if (m_Tainted) 432 if (m_Tainted)
@@ -459,9 +442,9 @@ namespace OpenSim.Region.CoreModules.World.Land
459 } 442 }
460 443
461// m_log.DebugFormat( 444// m_log.DebugFormat(
462// "[PRIM COUNT MODULE]: GetUserCount for user {0} in parcel {1} in region {2} returning {3}", 445// "[PRIM COUNT MODULE]: GetUserCount for user {0} in parcel {1} in region {2} returning {3}",
463// userID, parcelID, m_Scene.RegionInfo.RegionName, count); 446// userID, parcelID, m_Scene.RegionInfo.RegionName, count);
464 447
465 return count; 448 return count;
466 } 449 }
467 450
@@ -469,13 +452,13 @@ namespace OpenSim.Region.CoreModules.World.Land
469 private void Recount() 452 private void Recount()
470 { 453 {
471// m_log.DebugFormat("[PRIM COUNT MODULE]: Recounting prims on {0}", m_Scene.RegionInfo.RegionName); 454// m_log.DebugFormat("[PRIM COUNT MODULE]: Recounting prims on {0}", m_Scene.RegionInfo.RegionName);
472 455
473 m_OwnerMap.Clear(); 456 m_OwnerMap.Clear();
474 m_SimwideCounts.Clear(); 457 m_SimwideCounts.Clear();
475 m_ParcelCounts.Clear(); 458 m_ParcelCounts.Clear();
476 459
477 List<ILandObject> land = m_Scene.LandChannel.AllParcels(); 460 List<ILandObject> land = m_Scene.LandChannel.AllParcels();
478 461
479 foreach (ILandObject l in land) 462 foreach (ILandObject l in land)
480 { 463 {
481 LandData landData = l.LandData; 464 LandData landData = l.LandData;
@@ -483,7 +466,7 @@ namespace OpenSim.Region.CoreModules.World.Land
483 m_OwnerMap[landData.GlobalID] = landData.OwnerID; 466 m_OwnerMap[landData.GlobalID] = landData.OwnerID;
484 m_SimwideCounts[landData.OwnerID] = 0; 467 m_SimwideCounts[landData.OwnerID] = 0;
485// m_log.DebugFormat( 468// m_log.DebugFormat(
486// "[PRIM COUNT MODULE]: Initializing parcel count for {0} on {1}", 469// "[PRIM COUNT MODULE]: Initializing parcel count for {0} on {1}",
487// landData.Name, m_Scene.RegionInfo.RegionName); 470// landData.Name, m_Scene.RegionInfo.RegionName);
488 m_ParcelCounts[landData.GlobalID] = new ParcelCounts(); 471 m_ParcelCounts[landData.GlobalID] = new ParcelCounts();
489 } 472 }
@@ -499,7 +482,7 @@ namespace OpenSim.Region.CoreModules.World.Land
499 m_PrimCounts.Remove(k); 482 m_PrimCounts.Remove(k);
500 } 483 }
501 } 484 }
502 485
503 m_Tainted = false; 486 m_Tainted = false;
504 } 487 }
505 } 488 }
@@ -541,7 +524,7 @@ namespace OpenSim.Region.CoreModules.World.Land
541 return m_Parent.GetOthersCount(m_ParcelID); 524 return m_Parent.GetOthersCount(m_ParcelID);
542 } 525 }
543 } 526 }
544 527
545 public int Selected 528 public int Selected
546 { 529 {
547 get 530 get
@@ -549,7 +532,7 @@ namespace OpenSim.Region.CoreModules.World.Land
549 return m_Parent.GetSelectedCount(m_ParcelID); 532 return m_Parent.GetSelectedCount(m_ParcelID);
550 } 533 }
551 } 534 }
552 535
553 public int Total 536 public int Total
554 { 537 {
555 get 538 get
@@ -597,4 +580,4 @@ namespace OpenSim.Region.CoreModules.World.Land
597 } 580 }
598 } 581 }
599 } 582 }
600} \ No newline at end of file 583}
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs
index 4ed67f3..d6a3ded 100644
--- a/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs
+++ b/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs
@@ -45,14 +45,14 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
45 UUID userId = TestHelpers.ParseTail(0x1); 45 UUID userId = TestHelpers.ParseTail(0x1);
46 46
47 LandManagementModule lmm = new LandManagementModule(); 47 LandManagementModule lmm = new LandManagementModule();
48 Scene scene = new SceneHelpers().SetupScene(); 48 Scene scene = new SceneHelpers().SetupScene();
49 SceneHelpers.SetupSceneModules(scene, lmm); 49 SceneHelpers.SetupSceneModules(scene, lmm);
50 50
51 ILandObject lo = new LandObject(userId, false, scene); 51 ILandObject lo = new LandObject(userId, false, scene);
52 lo.LandData.Name = "lo1"; 52 lo.LandData.Name = "lo1";
53 lo.SetLandBitmap( 53 lo.SetLandBitmap(
54 lo.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 54 lo.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
55 lo = lmm.AddLandObject(lo); 55 lo = lmm.AddLandObject(lo);
56 56
57 // TODO: Should add asserts to check that land object was added properly. 57 // TODO: Should add asserts to check that land object was added properly.
58 58
@@ -67,7 +67,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
67 { 67 {
68 ILandObject loAtCoord = lmm.GetLandObject(0, 0); 68 ILandObject loAtCoord = lmm.GetLandObject(0, 0);
69 Assert.That(loAtCoord.LandData.LocalID, Is.EqualTo(lo.LandData.LocalID)); 69 Assert.That(loAtCoord.LandData.LocalID, Is.EqualTo(lo.LandData.LocalID));
70 Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(lo.LandData.GlobalID)); 70 Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(lo.LandData.GlobalID));
71 } 71 }
72 72
73 { 73 {
@@ -88,8 +88,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
88 88
89 SceneHelpers sh = new SceneHelpers(); 89 SceneHelpers sh = new SceneHelpers();
90 LandManagementModule lmm = new LandManagementModule(); 90 LandManagementModule lmm = new LandManagementModule();
91 Scene scene = sh.SetupScene(); 91 Scene scene = sh.SetupScene();
92 SceneHelpers.SetupSceneModules(scene, lmm); 92 SceneHelpers.SetupSceneModules(scene, lmm);
93 93
94 scene.loadAllLandObjectsFromStorage(scene.RegionInfo.RegionID); 94 scene.loadAllLandObjectsFromStorage(scene.RegionInfo.RegionID);
95 95
@@ -115,8 +115,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
115 115
116 SceneHelpers sh = new SceneHelpers(); 116 SceneHelpers sh = new SceneHelpers();
117 LandManagementModule lmm = new LandManagementModule(); 117 LandManagementModule lmm = new LandManagementModule();
118 Scene scene = sh.SetupScene(); 118 Scene scene = sh.SetupScene();
119 SceneHelpers.SetupSceneModules(scene, lmm); 119 SceneHelpers.SetupSceneModules(scene, lmm);
120 120
121 ILandObject originalLo1 = new LandObject(userId, false, scene); 121 ILandObject originalLo1 = new LandObject(userId, false, scene);
122 originalLo1.LandData.Name = "lo1"; 122 originalLo1.LandData.Name = "lo1";
@@ -149,8 +149,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
149 149
150 SceneHelpers sh = new SceneHelpers(); 150 SceneHelpers sh = new SceneHelpers();
151 LandManagementModule lmm = new LandManagementModule(); 151 LandManagementModule lmm = new LandManagementModule();
152 Scene scene = sh.SetupScene(); 152 Scene scene = sh.SetupScene();
153 SceneHelpers.SetupSceneModules(scene, lmm); 153 SceneHelpers.SetupSceneModules(scene, lmm);
154 154
155 ILandObject originalLo1 = new LandObject(userId, false, scene); 155 ILandObject originalLo1 = new LandObject(userId, false, scene);
156 originalLo1.LandData.Name = "lo1"; 156 originalLo1.LandData.Name = "lo1";
@@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
173 Assert.That(loAtCoord1.LandData.Name, Is.EqualTo(originalLo1.LandData.Name)); 173 Assert.That(loAtCoord1.LandData.Name, Is.EqualTo(originalLo1.LandData.Name));
174 Assert.That(loAtCoord1.LandData.GlobalID, Is.EqualTo(originalLo1.LandData.GlobalID)); 174 Assert.That(loAtCoord1.LandData.GlobalID, Is.EqualTo(originalLo1.LandData.GlobalID));
175 175
176 ILandObject loAtCoord2 176 ILandObject loAtCoord2
177 = lmm.GetLandObject((int)Constants.RegionSize - 1, (((int)Constants.RegionSize / 4) * 3) - 1); 177 = lmm.GetLandObject((int)Constants.RegionSize - 1, (((int)Constants.RegionSize / 4) * 3) - 1);
178 Assert.That(loAtCoord2.LandData.Name, Is.EqualTo(originalLo2.LandData.Name)); 178 Assert.That(loAtCoord2.LandData.Name, Is.EqualTo(originalLo2.LandData.Name));
179 Assert.That(loAtCoord2.LandData.GlobalID, Is.EqualTo(originalLo2.LandData.GlobalID)); 179 Assert.That(loAtCoord2.LandData.GlobalID, Is.EqualTo(originalLo2.LandData.GlobalID));
@@ -198,8 +198,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
198 198
199 SceneHelpers sh = new SceneHelpers(); 199 SceneHelpers sh = new SceneHelpers();
200 LandManagementModule lmm = new LandManagementModule(); 200 LandManagementModule lmm = new LandManagementModule();
201 Scene scene = sh.SetupScene(); 201 Scene scene = sh.SetupScene();
202 SceneHelpers.SetupSceneModules(scene, lmm); 202 SceneHelpers.SetupSceneModules(scene, lmm);
203 203
204 ILandObject originalLo1 = new LandObject(userId, false, scene); 204 ILandObject originalLo1 = new LandObject(userId, false, scene);
205 originalLo1.LandData.Name = "lo1"; 205 originalLo1.LandData.Name = "lo1";
@@ -220,7 +220,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
220 { 220 {
221 ILandObject loAtCoord = lmm.GetLandObject(0, 0); 221 ILandObject loAtCoord = lmm.GetLandObject(0, 0);
222 Assert.That(loAtCoord.LandData.Name, Is.EqualTo(originalLo1.LandData.Name)); 222 Assert.That(loAtCoord.LandData.Name, Is.EqualTo(originalLo1.LandData.Name));
223 Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(originalLo1.LandData.GlobalID)); 223 Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(originalLo1.LandData.GlobalID));
224 } 224 }
225 225
226 { 226 {
@@ -239,21 +239,21 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
239 UUID userId = TestHelpers.ParseTail(0x1); 239 UUID userId = TestHelpers.ParseTail(0x1);
240 240
241 LandManagementModule lmm = new LandManagementModule(); 241 LandManagementModule lmm = new LandManagementModule();
242 Scene scene = new SceneHelpers().SetupScene(); 242 Scene scene = new SceneHelpers().SetupScene();
243 SceneHelpers.SetupSceneModules(scene, lmm); 243 SceneHelpers.SetupSceneModules(scene, lmm);
244 244
245 ILandObject lo = new LandObject(userId, false, scene); 245 ILandObject lo = new LandObject(userId, false, scene);
246 lo.LandData.Name = "lo1"; 246 lo.LandData.Name = "lo1";
247 lo.SetLandBitmap( 247 lo.SetLandBitmap(
248 lo.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 248 lo.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
249 lo = lmm.AddLandObject(lo); 249 lo = lmm.AddLandObject(lo);
250 250
251 lmm.Subdivide(0, 0, LandManagementModule.LandUnit, LandManagementModule.LandUnit, userId); 251 lmm.Subdivide(0, 0, LandManagementModule.LandUnit, LandManagementModule.LandUnit, userId);
252 252
253 { 253 {
254 ILandObject loAtCoord = lmm.GetLandObject(0, 0); 254 ILandObject loAtCoord = lmm.GetLandObject(0, 0);
255 Assert.That(loAtCoord.LandData.LocalID, Is.Not.EqualTo(lo.LandData.LocalID)); 255 Assert.That(loAtCoord.LandData.LocalID, Is.Not.EqualTo(lo.LandData.LocalID));
256 Assert.That(loAtCoord.LandData.GlobalID, Is.Not.EqualTo(lo.LandData.GlobalID)); 256 Assert.That(loAtCoord.LandData.GlobalID, Is.Not.EqualTo(lo.LandData.GlobalID));
257 } 257 }
258 258
259 { 259 {
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
index 949acb6..a349aa1 100644
--- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
+++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
@@ -43,21 +43,21 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
43 public class PrimCountModuleTests : OpenSimTestCase 43 public class PrimCountModuleTests : OpenSimTestCase
44 { 44 {
45 protected UUID m_userId = new UUID("00000000-0000-0000-0000-100000000000"); 45 protected UUID m_userId = new UUID("00000000-0000-0000-0000-100000000000");
46 protected UUID m_groupId = new UUID("00000000-0000-0000-8888-000000000000"); 46 protected UUID m_groupId = new UUID("00000000-0000-0000-8888-000000000000");
47 protected UUID m_otherUserId = new UUID("99999999-9999-9999-9999-999999999999"); 47 protected UUID m_otherUserId = new UUID("99999999-9999-9999-9999-999999999999");
48 protected TestScene m_scene; 48 protected TestScene m_scene;
49 protected PrimCountModule m_pcm; 49 protected PrimCountModule m_pcm;
50 50
51 /// <summary> 51 /// <summary>
52 /// A parcel that covers the entire sim except for a 1 unit wide strip on the eastern side. 52 /// A parcel that covers the entire sim except for a 1 unit wide strip on the eastern side.
53 /// </summary> 53 /// </summary>
54 protected ILandObject m_lo; 54 protected ILandObject m_lo;
55 55
56 /// <summary> 56 /// <summary>
57 /// A parcel that covers just the eastern strip of the sim. 57 /// A parcel that covers just the eastern strip of the sim.
58 /// </summary> 58 /// </summary>
59 protected ILandObject m_lo2; 59 protected ILandObject m_lo2;
60 60
61 [SetUp] 61 [SetUp]
62 public override void SetUp() 62 public override void SetUp()
63 { 63 {
@@ -65,24 +65,24 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
65 65
66 m_pcm = new PrimCountModule(); 66 m_pcm = new PrimCountModule();
67 LandManagementModule lmm = new LandManagementModule(); 67 LandManagementModule lmm = new LandManagementModule();
68 m_scene = new SceneHelpers().SetupScene(); 68 m_scene = new SceneHelpers().SetupScene();
69 SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm); 69 SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm);
70 70
71 int xParcelDivider = (int)Constants.RegionSize - 1; 71 int xParcelDivider = (int)Constants.RegionSize - 1;
72 72
73 ILandObject lo = new LandObject(m_userId, false, m_scene); 73 ILandObject lo = new LandObject(m_userId, false, m_scene);
74 lo.LandData.Name = "m_lo"; 74 lo.LandData.Name = "m_lo";
75 lo.SetLandBitmap( 75 lo.SetLandBitmap(
76 lo.GetSquareLandBitmap(0, 0, xParcelDivider, (int)Constants.RegionSize)); 76 lo.GetSquareLandBitmap(0, 0, xParcelDivider, (int)Constants.RegionSize));
77 m_lo = lmm.AddLandObject(lo); 77 m_lo = lmm.AddLandObject(lo);
78 78
79 ILandObject lo2 = new LandObject(m_userId, false, m_scene); 79 ILandObject lo2 = new LandObject(m_userId, false, m_scene);
80 lo2.SetLandBitmap( 80 lo2.SetLandBitmap(
81 lo2.GetSquareLandBitmap(xParcelDivider, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 81 lo2.GetSquareLandBitmap(xParcelDivider, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
82 lo2.LandData.Name = "m_lo2"; 82 lo2.LandData.Name = "m_lo2";
83 m_lo2 = lmm.AddLandObject(lo2); 83 m_lo2 = lmm.AddLandObject(lo2);
84 } 84 }
85 85
86 /// <summary> 86 /// <summary>
87 /// Test that counts before we do anything are correct. 87 /// Test that counts before we do anything are correct.
88 /// </summary> 88 /// </summary>
@@ -90,7 +90,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
90 public void TestInitialCounts() 90 public void TestInitialCounts()
91 { 91 {
92 IPrimCounts pc = m_lo.PrimCounts; 92 IPrimCounts pc = m_lo.PrimCounts;
93 93
94 Assert.That(pc.Owner, Is.EqualTo(0)); 94 Assert.That(pc.Owner, Is.EqualTo(0));
95 Assert.That(pc.Group, Is.EqualTo(0)); 95 Assert.That(pc.Group, Is.EqualTo(0));
96 Assert.That(pc.Others, Is.EqualTo(0)); 96 Assert.That(pc.Others, Is.EqualTo(0));
@@ -98,9 +98,9 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
98 Assert.That(pc.Selected, Is.EqualTo(0)); 98 Assert.That(pc.Selected, Is.EqualTo(0));
99 Assert.That(pc.Users[m_userId], Is.EqualTo(0)); 99 Assert.That(pc.Users[m_userId], Is.EqualTo(0));
100 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0)); 100 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0));
101 Assert.That(pc.Simulator, Is.EqualTo(0)); 101 Assert.That(pc.Simulator, Is.EqualTo(0));
102 } 102 }
103 103
104 /// <summary> 104 /// <summary>
105 /// Test count after a parcel owner owned object is added. 105 /// Test count after a parcel owner owned object is added.
106 /// </summary> 106 /// </summary>
@@ -108,13 +108,13 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
108 public void TestAddOwnerObject() 108 public void TestAddOwnerObject()
109 { 109 {
110 TestHelpers.InMethod(); 110 TestHelpers.InMethod();
111// log4net.Config.XmlConfigurator.Configure(); 111// log4net.Config.XmlConfigurator.Configure();
112 112
113 IPrimCounts pc = m_lo.PrimCounts; 113 IPrimCounts pc = m_lo.PrimCounts;
114 114
115 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 115 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
116 m_scene.AddNewSceneObject(sog, false); 116 m_scene.AddNewSceneObject(sog, false);
117 117
118 Assert.That(pc.Owner, Is.EqualTo(3)); 118 Assert.That(pc.Owner, Is.EqualTo(3));
119 Assert.That(pc.Group, Is.EqualTo(0)); 119 Assert.That(pc.Group, Is.EqualTo(0));
120 Assert.That(pc.Others, Is.EqualTo(0)); 120 Assert.That(pc.Others, Is.EqualTo(0));
@@ -122,12 +122,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
122 Assert.That(pc.Selected, Is.EqualTo(0)); 122 Assert.That(pc.Selected, Is.EqualTo(0));
123 Assert.That(pc.Users[m_userId], Is.EqualTo(3)); 123 Assert.That(pc.Users[m_userId], Is.EqualTo(3));
124 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0)); 124 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0));
125 Assert.That(pc.Simulator, Is.EqualTo(3)); 125 Assert.That(pc.Simulator, Is.EqualTo(3));
126 126
127 // Add a second object and retest 127 // Add a second object and retest
128 SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10); 128 SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10);
129 m_scene.AddNewSceneObject(sog2, false); 129 m_scene.AddNewSceneObject(sog2, false);
130 130
131 Assert.That(pc.Owner, Is.EqualTo(5)); 131 Assert.That(pc.Owner, Is.EqualTo(5));
132 Assert.That(pc.Group, Is.EqualTo(0)); 132 Assert.That(pc.Group, Is.EqualTo(0));
133 Assert.That(pc.Others, Is.EqualTo(0)); 133 Assert.That(pc.Others, Is.EqualTo(0));
@@ -135,9 +135,9 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
135 Assert.That(pc.Selected, Is.EqualTo(0)); 135 Assert.That(pc.Selected, Is.EqualTo(0));
136 Assert.That(pc.Users[m_userId], Is.EqualTo(5)); 136 Assert.That(pc.Users[m_userId], Is.EqualTo(5));
137 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0)); 137 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0));
138 Assert.That(pc.Simulator, Is.EqualTo(5)); 138 Assert.That(pc.Simulator, Is.EqualTo(5));
139 } 139 }
140 140
141 /// <summary> 141 /// <summary>
142 /// Test count after a parcel owner owned copied object is added. 142 /// Test count after a parcel owner owned copied object is added.
143 /// </summary> 143 /// </summary>
@@ -145,14 +145,14 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
145 public void TestCopyOwnerObject() 145 public void TestCopyOwnerObject()
146 { 146 {
147 TestHelpers.InMethod(); 147 TestHelpers.InMethod();
148// log4net.Config.XmlConfigurator.Configure(); 148// log4net.Config.XmlConfigurator.Configure();
149 149
150 IPrimCounts pc = m_lo.PrimCounts; 150 IPrimCounts pc = m_lo.PrimCounts;
151 151
152 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 152 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
153 m_scene.AddNewSceneObject(sog, false); 153 m_scene.AddNewSceneObject(sog, false);
154 m_scene.SceneGraph.DuplicateObject(sog.LocalId, Vector3.Zero, 0, m_userId, UUID.Zero, Quaternion.Identity); 154 m_scene.SceneGraph.DuplicateObject(sog.LocalId, Vector3.Zero, m_userId, UUID.Zero, Quaternion.Identity, false);
155 155
156 Assert.That(pc.Owner, Is.EqualTo(6)); 156 Assert.That(pc.Owner, Is.EqualTo(6));
157 Assert.That(pc.Group, Is.EqualTo(0)); 157 Assert.That(pc.Group, Is.EqualTo(0));
158 Assert.That(pc.Others, Is.EqualTo(0)); 158 Assert.That(pc.Others, Is.EqualTo(0));
@@ -160,9 +160,9 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
160 Assert.That(pc.Selected, Is.EqualTo(0)); 160 Assert.That(pc.Selected, Is.EqualTo(0));
161 Assert.That(pc.Users[m_userId], Is.EqualTo(6)); 161 Assert.That(pc.Users[m_userId], Is.EqualTo(6));
162 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0)); 162 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0));
163 Assert.That(pc.Simulator, Is.EqualTo(6)); 163 Assert.That(pc.Simulator, Is.EqualTo(6));
164 } 164 }
165 165
166 /// <summary> 166 /// <summary>
167 /// Test that parcel counts update correctly when an object is moved between parcels, where that movement 167 /// Test that parcel counts update correctly when an object is moved between parcels, where that movement
168 /// is not done directly by the user/ 168 /// is not done directly by the user/
@@ -171,18 +171,18 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
171 public void TestMoveOwnerObject() 171 public void TestMoveOwnerObject()
172 { 172 {
173 TestHelpers.InMethod(); 173 TestHelpers.InMethod();
174// log4net.Config.XmlConfigurator.Configure(); 174// log4net.Config.XmlConfigurator.Configure();
175 175
176 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 176 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
177 m_scene.AddNewSceneObject(sog, false); 177 m_scene.AddNewSceneObject(sog, false);
178 SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10); 178 SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10);
179 m_scene.AddNewSceneObject(sog2, false); 179 m_scene.AddNewSceneObject(sog2, false);
180 180
181 // Move the first scene object to the eastern strip parcel 181 // Move the first scene object to the eastern strip parcel
182 sog.AbsolutePosition = new Vector3(254, 2, 2); 182 sog.AbsolutePosition = new Vector3(254, 2, 2);
183 183
184 IPrimCounts pclo1 = m_lo.PrimCounts; 184 IPrimCounts pclo1 = m_lo.PrimCounts;
185 185
186 Assert.That(pclo1.Owner, Is.EqualTo(2)); 186 Assert.That(pclo1.Owner, Is.EqualTo(2));
187 Assert.That(pclo1.Group, Is.EqualTo(0)); 187 Assert.That(pclo1.Group, Is.EqualTo(0));
188 Assert.That(pclo1.Others, Is.EqualTo(0)); 188 Assert.That(pclo1.Others, Is.EqualTo(0));
@@ -190,10 +190,10 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
190 Assert.That(pclo1.Selected, Is.EqualTo(0)); 190 Assert.That(pclo1.Selected, Is.EqualTo(0));
191 Assert.That(pclo1.Users[m_userId], Is.EqualTo(2)); 191 Assert.That(pclo1.Users[m_userId], Is.EqualTo(2));
192 Assert.That(pclo1.Users[m_otherUserId], Is.EqualTo(0)); 192 Assert.That(pclo1.Users[m_otherUserId], Is.EqualTo(0));
193 Assert.That(pclo1.Simulator, Is.EqualTo(5)); 193 Assert.That(pclo1.Simulator, Is.EqualTo(5));
194 194
195 IPrimCounts pclo2 = m_lo2.PrimCounts; 195 IPrimCounts pclo2 = m_lo2.PrimCounts;
196 196
197 Assert.That(pclo2.Owner, Is.EqualTo(3)); 197 Assert.That(pclo2.Owner, Is.EqualTo(3));
198 Assert.That(pclo2.Group, Is.EqualTo(0)); 198 Assert.That(pclo2.Group, Is.EqualTo(0));
199 Assert.That(pclo2.Others, Is.EqualTo(0)); 199 Assert.That(pclo2.Others, Is.EqualTo(0));
@@ -201,11 +201,11 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
201 Assert.That(pclo2.Selected, Is.EqualTo(0)); 201 Assert.That(pclo2.Selected, Is.EqualTo(0));
202 Assert.That(pclo2.Users[m_userId], Is.EqualTo(3)); 202 Assert.That(pclo2.Users[m_userId], Is.EqualTo(3));
203 Assert.That(pclo2.Users[m_otherUserId], Is.EqualTo(0)); 203 Assert.That(pclo2.Users[m_otherUserId], Is.EqualTo(0));
204 Assert.That(pclo2.Simulator, Is.EqualTo(5)); 204 Assert.That(pclo2.Simulator, Is.EqualTo(5));
205 205
206 // Now move it back again 206 // Now move it back again
207 sog.AbsolutePosition = new Vector3(2, 2, 2); 207 sog.AbsolutePosition = new Vector3(2, 2, 2);
208 208
209 Assert.That(pclo1.Owner, Is.EqualTo(5)); 209 Assert.That(pclo1.Owner, Is.EqualTo(5));
210 Assert.That(pclo1.Group, Is.EqualTo(0)); 210 Assert.That(pclo1.Group, Is.EqualTo(0));
211 Assert.That(pclo1.Others, Is.EqualTo(0)); 211 Assert.That(pclo1.Others, Is.EqualTo(0));
@@ -213,8 +213,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
213 Assert.That(pclo1.Selected, Is.EqualTo(0)); 213 Assert.That(pclo1.Selected, Is.EqualTo(0));
214 Assert.That(pclo1.Users[m_userId], Is.EqualTo(5)); 214 Assert.That(pclo1.Users[m_userId], Is.EqualTo(5));
215 Assert.That(pclo1.Users[m_otherUserId], Is.EqualTo(0)); 215 Assert.That(pclo1.Users[m_otherUserId], Is.EqualTo(0));
216 Assert.That(pclo1.Simulator, Is.EqualTo(5)); 216 Assert.That(pclo1.Simulator, Is.EqualTo(5));
217 217
218 Assert.That(pclo2.Owner, Is.EqualTo(0)); 218 Assert.That(pclo2.Owner, Is.EqualTo(0));
219 Assert.That(pclo2.Group, Is.EqualTo(0)); 219 Assert.That(pclo2.Group, Is.EqualTo(0));
220 Assert.That(pclo2.Others, Is.EqualTo(0)); 220 Assert.That(pclo2.Others, Is.EqualTo(0));
@@ -222,9 +222,9 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
222 Assert.That(pclo2.Selected, Is.EqualTo(0)); 222 Assert.That(pclo2.Selected, Is.EqualTo(0));
223 Assert.That(pclo2.Users[m_userId], Is.EqualTo(0)); 223 Assert.That(pclo2.Users[m_userId], Is.EqualTo(0));
224 Assert.That(pclo2.Users[m_otherUserId], Is.EqualTo(0)); 224 Assert.That(pclo2.Users[m_otherUserId], Is.EqualTo(0));
225 Assert.That(pclo2.Simulator, Is.EqualTo(5)); 225 Assert.That(pclo2.Simulator, Is.EqualTo(5));
226 } 226 }
227 227
228 /// <summary> 228 /// <summary>
229 /// Test count after a parcel owner owned object is removed. 229 /// Test count after a parcel owner owned object is removed.
230 /// </summary> 230 /// </summary>
@@ -233,14 +233,14 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
233 { 233 {
234 TestHelpers.InMethod(); 234 TestHelpers.InMethod();
235// log4net.Config.XmlConfigurator.Configure(); 235// log4net.Config.XmlConfigurator.Configure();
236 236
237 IPrimCounts pc = m_lo.PrimCounts; 237 IPrimCounts pc = m_lo.PrimCounts;
238 238
239 m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1), false); 239 m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1), false);
240 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10); 240 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10);
241 m_scene.AddNewSceneObject(sogToDelete, false); 241 m_scene.AddNewSceneObject(sogToDelete, false);
242 m_scene.DeleteSceneObject(sogToDelete, false); 242 m_scene.DeleteSceneObject(sogToDelete, false);
243 243
244 Assert.That(pc.Owner, Is.EqualTo(1)); 244 Assert.That(pc.Owner, Is.EqualTo(1));
245 Assert.That(pc.Group, Is.EqualTo(0)); 245 Assert.That(pc.Group, Is.EqualTo(0));
246 Assert.That(pc.Others, Is.EqualTo(0)); 246 Assert.That(pc.Others, Is.EqualTo(0));
@@ -248,37 +248,37 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
248 Assert.That(pc.Selected, Is.EqualTo(0)); 248 Assert.That(pc.Selected, Is.EqualTo(0));
249 Assert.That(pc.Users[m_userId], Is.EqualTo(1)); 249 Assert.That(pc.Users[m_userId], Is.EqualTo(1));
250 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0)); 250 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0));
251 Assert.That(pc.Simulator, Is.EqualTo(1)); 251 Assert.That(pc.Simulator, Is.EqualTo(1));
252 } 252 }
253 253
254 [Test] 254 [Test]
255 public void TestAddGroupObject() 255 public void TestAddGroupObject()
256 { 256 {
257 TestHelpers.InMethod(); 257 TestHelpers.InMethod();
258// log4net.Config.XmlConfigurator.Configure(); 258// log4net.Config.XmlConfigurator.Configure();
259 259
260 m_lo.DeedToGroup(m_groupId); 260 m_lo.DeedToGroup(m_groupId);
261 261
262 IPrimCounts pc = m_lo.PrimCounts; 262 IPrimCounts pc = m_lo.PrimCounts;
263 263
264 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); 264 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01);
265 sog.GroupID = m_groupId; 265 sog.GroupID = m_groupId;
266 m_scene.AddNewSceneObject(sog, false); 266 m_scene.AddNewSceneObject(sog, false);
267 267
268 Assert.That(pc.Owner, Is.EqualTo(0)); 268 Assert.That(pc.Owner, Is.EqualTo(0));
269 Assert.That(pc.Group, Is.EqualTo(3)); 269 Assert.That(pc.Group, Is.EqualTo(3));
270 Assert.That(pc.Others, Is.EqualTo(0)); 270 Assert.That(pc.Others, Is.EqualTo(0));
271 Assert.That(pc.Total, Is.EqualTo(3)); 271 Assert.That(pc.Total, Is.EqualTo(3));
272 Assert.That(pc.Selected, Is.EqualTo(0)); 272 Assert.That(pc.Selected, Is.EqualTo(0));
273 273
274 // Is this desired behaviour? Not totally sure. 274 // Is this desired behaviour? Not totally sure.
275 Assert.That(pc.Users[m_userId], Is.EqualTo(0)); 275 Assert.That(pc.Users[m_userId], Is.EqualTo(0));
276 Assert.That(pc.Users[m_groupId], Is.EqualTo(0)); 276 Assert.That(pc.Users[m_groupId], Is.EqualTo(0));
277 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(3)); 277 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(3));
278 278
279 Assert.That(pc.Simulator, Is.EqualTo(3)); 279 Assert.That(pc.Simulator, Is.EqualTo(3));
280 } 280 }
281 281
282 /// <summary> 282 /// <summary>
283 /// Test count after a parcel owner owned object is removed. 283 /// Test count after a parcel owner owned object is removed.
284 /// </summary> 284 /// </summary>
@@ -287,19 +287,19 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
287 { 287 {
288 TestHelpers.InMethod(); 288 TestHelpers.InMethod();
289// log4net.Config.XmlConfigurator.Configure(); 289// log4net.Config.XmlConfigurator.Configure();
290 290
291 m_lo.DeedToGroup(m_groupId); 291 m_lo.DeedToGroup(m_groupId);
292 292
293 IPrimCounts pc = m_lo.PrimCounts; 293 IPrimCounts pc = m_lo.PrimCounts;
294 294
295 SceneObjectGroup sogToKeep = SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1); 295 SceneObjectGroup sogToKeep = SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1);
296 sogToKeep.GroupID = m_groupId; 296 sogToKeep.GroupID = m_groupId;
297 m_scene.AddNewSceneObject(sogToKeep, false); 297 m_scene.AddNewSceneObject(sogToKeep, false);
298 298
299 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10); 299 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10);
300 m_scene.AddNewSceneObject(sogToDelete, false); 300 m_scene.AddNewSceneObject(sogToDelete, false);
301 m_scene.DeleteSceneObject(sogToDelete, false); 301 m_scene.DeleteSceneObject(sogToDelete, false);
302 302
303 Assert.That(pc.Owner, Is.EqualTo(0)); 303 Assert.That(pc.Owner, Is.EqualTo(0));
304 Assert.That(pc.Group, Is.EqualTo(1)); 304 Assert.That(pc.Group, Is.EqualTo(1));
305 Assert.That(pc.Others, Is.EqualTo(0)); 305 Assert.That(pc.Others, Is.EqualTo(0));
@@ -308,20 +308,20 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
308 Assert.That(pc.Users[m_userId], Is.EqualTo(1)); 308 Assert.That(pc.Users[m_userId], Is.EqualTo(1));
309 Assert.That(pc.Users[m_groupId], Is.EqualTo(0)); 309 Assert.That(pc.Users[m_groupId], Is.EqualTo(0));
310 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0)); 310 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0));
311 Assert.That(pc.Simulator, Is.EqualTo(1)); 311 Assert.That(pc.Simulator, Is.EqualTo(1));
312 } 312 }
313 313
314 [Test] 314 [Test]
315 public void TestAddOthersObject() 315 public void TestAddOthersObject()
316 { 316 {
317 TestHelpers.InMethod(); 317 TestHelpers.InMethod();
318// log4net.Config.XmlConfigurator.Configure(); 318// log4net.Config.XmlConfigurator.Configure();
319 319
320 IPrimCounts pc = m_lo.PrimCounts; 320 IPrimCounts pc = m_lo.PrimCounts;
321 321
322 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); 322 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01);
323 m_scene.AddNewSceneObject(sog, false); 323 m_scene.AddNewSceneObject(sog, false);
324 324
325 Assert.That(pc.Owner, Is.EqualTo(0)); 325 Assert.That(pc.Owner, Is.EqualTo(0));
326 Assert.That(pc.Group, Is.EqualTo(0)); 326 Assert.That(pc.Group, Is.EqualTo(0));
327 Assert.That(pc.Others, Is.EqualTo(3)); 327 Assert.That(pc.Others, Is.EqualTo(3));
@@ -329,22 +329,22 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
329 Assert.That(pc.Selected, Is.EqualTo(0)); 329 Assert.That(pc.Selected, Is.EqualTo(0));
330 Assert.That(pc.Users[m_userId], Is.EqualTo(0)); 330 Assert.That(pc.Users[m_userId], Is.EqualTo(0));
331 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(3)); 331 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(3));
332 Assert.That(pc.Simulator, Is.EqualTo(3)); 332 Assert.That(pc.Simulator, Is.EqualTo(3));
333 } 333 }
334 334
335 [Test] 335 [Test]
336 public void TestRemoveOthersObject() 336 public void TestRemoveOthersObject()
337 { 337 {
338 TestHelpers.InMethod(); 338 TestHelpers.InMethod();
339// log4net.Config.XmlConfigurator.Configure(); 339// log4net.Config.XmlConfigurator.Configure();
340 340
341 IPrimCounts pc = m_lo.PrimCounts; 341 IPrimCounts pc = m_lo.PrimCounts;
342 342
343 m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_otherUserId, "a", 0x1), false); 343 m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_otherUserId, "a", 0x1), false);
344 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_otherUserId, "b", 0x10); 344 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_otherUserId, "b", 0x10);
345 m_scene.AddNewSceneObject(sogToDelete, false); 345 m_scene.AddNewSceneObject(sogToDelete, false);
346 m_scene.DeleteSceneObject(sogToDelete, false); 346 m_scene.DeleteSceneObject(sogToDelete, false);
347 347
348 Assert.That(pc.Owner, Is.EqualTo(0)); 348 Assert.That(pc.Owner, Is.EqualTo(0));
349 Assert.That(pc.Group, Is.EqualTo(0)); 349 Assert.That(pc.Group, Is.EqualTo(0));
350 Assert.That(pc.Others, Is.EqualTo(1)); 350 Assert.That(pc.Others, Is.EqualTo(1));
@@ -352,9 +352,9 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
352 Assert.That(pc.Selected, Is.EqualTo(0)); 352 Assert.That(pc.Selected, Is.EqualTo(0));
353 Assert.That(pc.Users[m_userId], Is.EqualTo(0)); 353 Assert.That(pc.Users[m_userId], Is.EqualTo(0));
354 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(1)); 354 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(1));
355 Assert.That(pc.Simulator, Is.EqualTo(1)); 355 Assert.That(pc.Simulator, Is.EqualTo(1));
356 } 356 }
357 357
358 /// <summary> 358 /// <summary>
359 /// Test the count is correct after is has been tainted. 359 /// Test the count is correct after is has been tainted.
360 /// </summary> 360 /// </summary>
@@ -363,12 +363,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
363 { 363 {
364 TestHelpers.InMethod(); 364 TestHelpers.InMethod();
365 IPrimCounts pc = m_lo.PrimCounts; 365 IPrimCounts pc = m_lo.PrimCounts;
366 366
367 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 367 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
368 m_scene.AddNewSceneObject(sog, false); 368 m_scene.AddNewSceneObject(sog, false);
369 369
370 m_pcm.TaintPrimCount(); 370 m_pcm.TaintPrimCount();
371 371
372 Assert.That(pc.Owner, Is.EqualTo(3)); 372 Assert.That(pc.Owner, Is.EqualTo(3));
373 Assert.That(pc.Group, Is.EqualTo(0)); 373 Assert.That(pc.Group, Is.EqualTo(0));
374 Assert.That(pc.Others, Is.EqualTo(0)); 374 Assert.That(pc.Others, Is.EqualTo(0));
@@ -376,7 +376,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
376 Assert.That(pc.Selected, Is.EqualTo(0)); 376 Assert.That(pc.Selected, Is.EqualTo(0));
377 Assert.That(pc.Users[m_userId], Is.EqualTo(3)); 377 Assert.That(pc.Users[m_userId], Is.EqualTo(3));
378 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0)); 378 Assert.That(pc.Users[m_otherUserId], Is.EqualTo(0));
379 Assert.That(pc.Simulator, Is.EqualTo(3)); 379 Assert.That(pc.Simulator, Is.EqualTo(3));
380 } 380 }
381 } 381 }
382} \ No newline at end of file 382} \ No newline at end of file