aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs1998
1 files changed, 999 insertions, 999 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs b/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs
index efc5234..9ac3cc3 100644
--- a/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs
@@ -1,1000 +1,1000 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using Axiom.Math; 30using Axiom.Math;
31using libsecondlife; 31using libsecondlife;
32using libsecondlife.Packets; 32using libsecondlife.Packets;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces; 34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes; 35using OpenSim.Region.Environment.Scenes;
36using OpenSim.Region.Physics.Manager; 36using OpenSim.Region.Physics.Manager;
37 37
38namespace OpenSim.Region.Environment.Modules.World.Land 38namespace OpenSim.Region.Environment.Modules.World.Land
39{ 39{
40 public class LandChannel : ILandChannel 40 public class LandChannel : ILandChannel
41 { 41 {
42 #region Constants 42 #region Constants
43 43
44 //Land types set with flags in ParcelOverlay. 44 //Land types set with flags in ParcelOverlay.
45 //Only one of these can be used. 45 //Only one of these can be used.
46 public const float BAN_LINE_SAFETY_HIEGHT = 100; 46 public const float BAN_LINE_SAFETY_HIEGHT = 100;
47 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte) 128; //Equals 10000000 47 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte) 128; //Equals 10000000
48 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte) 64; //Equals 01000000 48 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte) 64; //Equals 01000000
49 49
50 //RequestResults (I think these are right, they seem to work): 50 //RequestResults (I think these are right, they seem to work):
51 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land 51 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land
52 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land 52 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land
53 53
54 //ParcelSelectObjects 54 //ParcelSelectObjects
55 public const int LAND_SELECT_OBJECTS_GROUP = 4; 55 public const int LAND_SELECT_OBJECTS_GROUP = 4;
56 public const int LAND_SELECT_OBJECTS_OTHER = 8; 56 public const int LAND_SELECT_OBJECTS_OTHER = 8;
57 public const int LAND_SELECT_OBJECTS_OWNER = 2; 57 public const int LAND_SELECT_OBJECTS_OWNER = 2;
58 public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte) 5; //Equals 00000101 58 public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte) 5; //Equals 00000101
59 public const byte LAND_TYPE_IS_FOR_SALE = (byte) 4; //Equals 00000100 59 public const byte LAND_TYPE_IS_FOR_SALE = (byte) 4; //Equals 00000100
60 public const byte LAND_TYPE_OWNED_BY_GROUP = (byte) 2; //Equals 00000010 60 public const byte LAND_TYPE_OWNED_BY_GROUP = (byte) 2; //Equals 00000010
61 public const byte LAND_TYPE_OWNED_BY_OTHER = (byte) 1; //Equals 00000001 61 public const byte LAND_TYPE_OWNED_BY_OTHER = (byte) 1; //Equals 00000001
62 public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte) 3; //Equals 00000011 62 public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte) 3; //Equals 00000011
63 public const byte LAND_TYPE_PUBLIC = (byte) 0; //Equals 00000000 63 public const byte LAND_TYPE_PUBLIC = (byte) 0; //Equals 00000000
64 64
65 //These are other constants. Yay! 65 //These are other constants. Yay!
66 public const int START_LAND_LOCAL_ID = 1; 66 public const int START_LAND_LOCAL_ID = 1;
67 67
68 #endregion 68 #endregion
69 69
70 private int[,] landIDList = new int[64,64]; 70 private int[,] landIDList = new int[64,64];
71 private Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>(); 71 private Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>();
72 72
73 private bool landPrimCountTainted = false; 73 private bool landPrimCountTainted = false;
74 private int lastLandLocalID = START_LAND_LOCAL_ID - 1; 74 private int lastLandLocalID = START_LAND_LOCAL_ID - 1;
75 75
76 private bool m_allowedForcefulBans = true; 76 private bool m_allowedForcefulBans = true;
77 private Scene m_scene; 77 private Scene m_scene;
78 78
79 public LandChannel(Scene scene) 79 public LandChannel(Scene scene)
80 { 80 {
81 m_scene = scene; 81 m_scene = scene;
82 landIDList.Initialize(); 82 landIDList.Initialize();
83 } 83 }
84 84
85 #region Land Object From Storage Functions 85 #region Land Object From Storage Functions
86 86
87 public void IncomingLandObjectsFromStorage(List<LandData> data) 87 public void IncomingLandObjectsFromStorage(List<LandData> data)
88 { 88 {
89 for (int i = 0; i < data.Count; i++) 89 for (int i = 0; i < data.Count; i++)
90 { 90 {
91 //try 91 //try
92 //{ 92 //{
93 IncomingLandObjectFromStorage(data[i]); 93 IncomingLandObjectFromStorage(data[i]);
94 //} 94 //}
95 //catch (Exception ex) 95 //catch (Exception ex)
96 //{ 96 //{
97 //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString()); 97 //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString());
98 //throw ex; 98 //throw ex;
99 //} 99 //}
100 } 100 }
101 //foreach (LandData parcel in data) 101 //foreach (LandData parcel in data)
102 //{ 102 //{
103 // IncomingLandObjectFromStorage(parcel); 103 // IncomingLandObjectFromStorage(parcel);
104 //} 104 //}
105 } 105 }
106 106
107 public void IncomingLandObjectFromStorage(LandData data) 107 public void IncomingLandObjectFromStorage(LandData data)
108 { 108 {
109 ILandObject new_land = new LandObject(data.ownerID, data.isGroupOwned, m_scene); 109 ILandObject new_land = new LandObject(data.ownerID, data.isGroupOwned, m_scene);
110 new_land.landData = data.Copy(); 110 new_land.landData = data.Copy();
111 new_land.setLandBitmapFromByteArray(); 111 new_land.setLandBitmapFromByteArray();
112 addLandObject(new_land); 112 addLandObject(new_land);
113 } 113 }
114 114
115 public void NoLandDataFromStorage() 115 public void NoLandDataFromStorage()
116 { 116 {
117 resetSimLandObjects(); 117 resetSimLandObjects();
118 } 118 }
119 119
120 #endregion 120 #endregion
121 121
122 #region Parcel Add/Remove/Get/Create 122 #region Parcel Add/Remove/Get/Create
123 123
124 public void updateLandObject(int local_id, LandData newData) 124 public void updateLandObject(int local_id, LandData newData)
125 { 125 {
126 if (landList.ContainsKey(local_id)) 126 if (landList.ContainsKey(local_id))
127 { 127 {
128 landList[local_id].landData = newData.Copy(); 128 landList[local_id].landData = newData.Copy();
129 m_scene.EventManager.TriggerLandObjectUpdated((uint) local_id, landList[local_id]); 129 m_scene.EventManager.TriggerLandObjectUpdated((uint) local_id, landList[local_id]);
130 } 130 }
131 } 131 }
132 132
133 /// <summary> 133 /// <summary>
134 /// Get the land object at the specified point 134 /// Get the land object at the specified point
135 /// </summary> 135 /// </summary>
136 /// <param name="x">Value between 0 - 256 on the x axis of the point</param> 136 /// <param name="x">Value between 0 - 256 on the x axis of the point</param>
137 /// <param name="y">Value between 0 - 256 on the y axis of the point</param> 137 /// <param name="y">Value between 0 - 256 on the y axis of the point</param>
138 /// <returns>Land object at the point supplied</returns> 138 /// <returns>Land object at the point supplied</returns>
139 public ILandObject getLandObject(float x_float, float y_float) 139 public ILandObject getLandObject(float x_float, float y_float)
140 { 140 {
141 int x; 141 int x;
142 int y; 142 int y;
143 143
144 try 144 try
145 { 145 {
146 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / Convert.ToDouble(4.0))); 146 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / Convert.ToDouble(4.0)));
147 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / Convert.ToDouble(4.0))); 147 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / Convert.ToDouble(4.0)));
148 } 148 }
149 catch (OverflowException) 149 catch (OverflowException)
150 { 150 {
151 return null; 151 return null;
152 } 152 }
153 153
154 if (x >= 64 || y >= 64 || x < 0 || y < 0) 154 if (x >= 64 || y >= 64 || x < 0 || y < 0)
155 { 155 {
156 return null; 156 return null;
157 } 157 }
158 else 158 else
159 { 159 {
160 return landList[landIDList[x, y]]; 160 return landList[landIDList[x, y]];
161 } 161 }
162 } 162 }
163 163
164 public ILandObject getLandObject(int x, int y) 164 public ILandObject getLandObject(int x, int y)
165 { 165 {
166 if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0) 166 if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0)
167 { 167 {
168 // These exceptions here will cause a lot of complaints from the users specifically because 168 // These exceptions here will cause a lot of complaints from the users specifically because
169 // they happen every time at border crossings 169 // they happen every time at border crossings
170 throw new Exception("Error: Parcel not found at point " + x + ", " + y); 170 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
171 } 171 }
172 else 172 else
173 { 173 {
174 return landList[landIDList[x / 4, y / 4]]; 174 return landList[landIDList[x / 4, y / 4]];
175 } 175 }
176 } 176 }
177 177
178 /// <summary> 178 /// <summary>
179 /// Creates a basic Parcel object without an owner (a zeroed key) 179 /// Creates a basic Parcel object without an owner (a zeroed key)
180 /// </summary> 180 /// </summary>
181 /// <returns></returns> 181 /// <returns></returns>
182 public ILandObject createBaseLand() 182 public ILandObject createBaseLand()
183 { 183 {
184 return new LandObject(LLUUID.Zero, false, m_scene); 184 return new LandObject(LLUUID.Zero, false, m_scene);
185 } 185 }
186 186
187 /// <summary> 187 /// <summary>
188 /// Adds a land object to the stored list and adds them to the landIDList to what they own 188 /// Adds a land object to the stored list and adds them to the landIDList to what they own
189 /// </summary> 189 /// </summary>
190 /// <param name="new_land">The land object being added</param> 190 /// <param name="new_land">The land object being added</param>
191 public ILandObject addLandObject(ILandObject new_land) 191 public ILandObject addLandObject(ILandObject new_land)
192 { 192 {
193 lastLandLocalID++; 193 lastLandLocalID++;
194 new_land.landData.localID = lastLandLocalID; 194 new_land.landData.localID = lastLandLocalID;
195 landList.Add(lastLandLocalID, (LandObject) new_land.Copy()); 195 landList.Add(lastLandLocalID, (LandObject) new_land.Copy());
196 196
197 197
198 bool[,] landBitmap = new_land.getLandBitmap(); 198 bool[,] landBitmap = new_land.getLandBitmap();
199 int x, y; 199 int x, y;
200 for (x = 0; x < 64; x++) 200 for (x = 0; x < 64; x++)
201 { 201 {
202 for (y = 0; y < 64; y++) 202 for (y = 0; y < 64; y++)
203 { 203 {
204 if (landBitmap[x, y]) 204 if (landBitmap[x, y])
205 { 205 {
206 landIDList[x, y] = lastLandLocalID; 206 landIDList[x, y] = lastLandLocalID;
207 } 207 }
208 } 208 }
209 } 209 }
210 landList[lastLandLocalID].forceUpdateLandInfo(); 210 landList[lastLandLocalID].forceUpdateLandInfo();
211 m_scene.EventManager.TriggerLandObjectAdded(new_land); 211 m_scene.EventManager.TriggerLandObjectAdded(new_land);
212 return new_land; 212 return new_land;
213 } 213 }
214 214
215 /// <summary> 215 /// <summary>
216 /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList 216 /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList
217 /// </summary> 217 /// </summary>
218 /// <param name="local_id">Land.localID of the peice of land to remove.</param> 218 /// <param name="local_id">Land.localID of the peice of land to remove.</param>
219 public void removeLandObject(int local_id) 219 public void removeLandObject(int local_id)
220 { 220 {
221 int x, y; 221 int x, y;
222 for (x = 0; x < 64; x++) 222 for (x = 0; x < 64; x++)
223 { 223 {
224 for (y = 0; y < 64; y++) 224 for (y = 0; y < 64; y++)
225 { 225 {
226 if (landIDList[x, y] == local_id) 226 if (landIDList[x, y] == local_id)
227 { 227 {
228 return; 228 return;
229 //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); 229 //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y);
230 } 230 }
231 } 231 }
232 } 232 }
233 233
234 m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.globalID); 234 m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.globalID);
235 landList.Remove(local_id); 235 landList.Remove(local_id);
236 } 236 }
237 237
238 private void performFinalLandJoin(ILandObject master, ILandObject slave) 238 private void performFinalLandJoin(ILandObject master, ILandObject slave)
239 { 239 {
240 int x, y; 240 int x, y;
241 bool[,] landBitmapSlave = slave.getLandBitmap(); 241 bool[,] landBitmapSlave = slave.getLandBitmap();
242 for (x = 0; x < 64; x++) 242 for (x = 0; x < 64; x++)
243 { 243 {
244 for (y = 0; y < 64; y++) 244 for (y = 0; y < 64; y++)
245 { 245 {
246 if (landBitmapSlave[x, y]) 246 if (landBitmapSlave[x, y])
247 { 247 {
248 landIDList[x, y] = master.landData.localID; 248 landIDList[x, y] = master.landData.localID;
249 } 249 }
250 } 250 }
251 } 251 }
252 252
253 removeLandObject(slave.landData.localID); 253 removeLandObject(slave.landData.localID);
254 updateLandObject(master.landData.localID, master.landData); 254 updateLandObject(master.landData.localID, master.landData);
255 } 255 }
256 256
257 public ILandObject getLandObject(int parcelLocalID) 257 public ILandObject getLandObject(int parcelLocalID)
258 { 258 {
259 lock (landList) 259 lock (landList)
260 { 260 {
261 if (landList.ContainsKey(parcelLocalID)) 261 if (landList.ContainsKey(parcelLocalID))
262 { 262 {
263 return landList[parcelLocalID]; 263 return landList[parcelLocalID];
264 } 264 }
265 } 265 }
266 return null; 266 return null;
267 } 267 }
268 268
269 #endregion 269 #endregion
270 270
271 #region Parcel Modification 271 #region Parcel Modification
272 272
273 public void resetAllLandPrimCounts() 273 public void resetAllLandPrimCounts()
274 { 274 {
275 foreach (LandObject p in landList.Values) 275 foreach (LandObject p in landList.Values)
276 { 276 {
277 p.resetLandPrimCounts(); 277 p.resetLandPrimCounts();
278 } 278 }
279 } 279 }
280 280
281 public void setPrimsTainted() 281 public void setPrimsTainted()
282 { 282 {
283 landPrimCountTainted = true; 283 landPrimCountTainted = true;
284 } 284 }
285 285
286 public bool isLandPrimCountTainted() 286 public bool isLandPrimCountTainted()
287 { 287 {
288 return landPrimCountTainted; 288 return landPrimCountTainted;
289 } 289 }
290 290
291 public void addPrimToLandPrimCounts(SceneObjectGroup obj) 291 public void addPrimToLandPrimCounts(SceneObjectGroup obj)
292 { 292 {
293 LLVector3 position = obj.AbsolutePosition; 293 LLVector3 position = obj.AbsolutePosition;
294 ILandObject landUnderPrim = getLandObject(position.X, position.Y); 294 ILandObject landUnderPrim = getLandObject(position.X, position.Y);
295 if (landUnderPrim != null) 295 if (landUnderPrim != null)
296 { 296 {
297 landUnderPrim.addPrimToCount(obj); 297 landUnderPrim.addPrimToCount(obj);
298 } 298 }
299 } 299 }
300 300
301 public void removePrimFromLandPrimCounts(SceneObjectGroup obj) 301 public void removePrimFromLandPrimCounts(SceneObjectGroup obj)
302 { 302 {
303 foreach (LandObject p in landList.Values) 303 foreach (LandObject p in landList.Values)
304 { 304 {
305 p.removePrimFromCount(obj); 305 p.removePrimFromCount(obj);
306 } 306 }
307 } 307 }
308 308
309 public void finalizeLandPrimCountUpdate() 309 public void finalizeLandPrimCountUpdate()
310 { 310 {
311 //Get Simwide prim count for owner 311 //Get Simwide prim count for owner
312 Dictionary<LLUUID, List<LandObject>> landOwnersAndParcels = new Dictionary<LLUUID, List<LandObject>>(); 312 Dictionary<LLUUID, List<LandObject>> landOwnersAndParcels = new Dictionary<LLUUID, List<LandObject>>();
313 foreach (LandObject p in landList.Values) 313 foreach (LandObject p in landList.Values)
314 { 314 {
315 if (!landOwnersAndParcels.ContainsKey(p.landData.ownerID)) 315 if (!landOwnersAndParcels.ContainsKey(p.landData.ownerID))
316 { 316 {
317 List<LandObject> tempList = new List<LandObject>(); 317 List<LandObject> tempList = new List<LandObject>();
318 tempList.Add(p); 318 tempList.Add(p);
319 landOwnersAndParcels.Add(p.landData.ownerID, tempList); 319 landOwnersAndParcels.Add(p.landData.ownerID, tempList);
320 } 320 }
321 else 321 else
322 { 322 {
323 landOwnersAndParcels[p.landData.ownerID].Add(p); 323 landOwnersAndParcels[p.landData.ownerID].Add(p);
324 } 324 }
325 } 325 }
326 326
327 foreach (LLUUID owner in landOwnersAndParcels.Keys) 327 foreach (LLUUID owner in landOwnersAndParcels.Keys)
328 { 328 {
329 int simArea = 0; 329 int simArea = 0;
330 int simPrims = 0; 330 int simPrims = 0;
331 foreach (LandObject p in landOwnersAndParcels[owner]) 331 foreach (LandObject p in landOwnersAndParcels[owner])
332 { 332 {
333 simArea += p.landData.area; 333 simArea += p.landData.area;
334 simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims + 334 simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims +
335 p.landData.selectedPrims; 335 p.landData.selectedPrims;
336 } 336 }
337 337
338 foreach (LandObject p in landOwnersAndParcels[owner]) 338 foreach (LandObject p in landOwnersAndParcels[owner])
339 { 339 {
340 p.landData.simwideArea = simArea; 340 p.landData.simwideArea = simArea;
341 p.landData.simwidePrims = simPrims; 341 p.landData.simwidePrims = simPrims;
342 } 342 }
343 } 343 }
344 } 344 }
345 345
346 public void updateLandPrimCounts() 346 public void updateLandPrimCounts()
347 { 347 {
348 foreach (EntityBase obj in m_scene.Entities.Values) 348 foreach (EntityBase obj in m_scene.Entities.Values)
349 { 349 {
350 if (obj is SceneObjectGroup) 350 if (obj is SceneObjectGroup)
351 { 351 {
352 m_scene.EventManager.TriggerParcelPrimCountAdd((SceneObjectGroup) obj); 352 m_scene.EventManager.TriggerParcelPrimCountAdd((SceneObjectGroup) obj);
353 } 353 }
354 } 354 }
355 } 355 }
356 356
357 public void performParcelPrimCountUpdate() 357 public void performParcelPrimCountUpdate()
358 { 358 {
359 resetAllLandPrimCounts(); 359 resetAllLandPrimCounts();
360 m_scene.EventManager.TriggerParcelPrimCountUpdate(); 360 m_scene.EventManager.TriggerParcelPrimCountUpdate();
361 finalizeLandPrimCountUpdate(); 361 finalizeLandPrimCountUpdate();
362 landPrimCountTainted = false; 362 landPrimCountTainted = false;
363 } 363 }
364 364
365 /// <summary> 365 /// <summary>
366 /// Subdivides a piece of land 366 /// Subdivides a piece of land
367 /// </summary> 367 /// </summary>
368 /// <param name="start_x">West Point</param> 368 /// <param name="start_x">West Point</param>
369 /// <param name="start_y">South Point</param> 369 /// <param name="start_y">South Point</param>
370 /// <param name="end_x">East Point</param> 370 /// <param name="end_x">East Point</param>
371 /// <param name="end_y">North Point</param> 371 /// <param name="end_y">North Point</param>
372 /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param> 372 /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param>
373 /// <returns>Returns true if successful</returns> 373 /// <returns>Returns true if successful</returns>
374 private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) 374 private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
375 { 375 {
376 //First, lets loop through the points and make sure they are all in the same peice of land 376 //First, lets loop through the points and make sure they are all in the same peice of land
377 //Get the land object at start 377 //Get the land object at start
378 ILandObject startLandObject = null; 378 ILandObject startLandObject = null;
379 try 379 try
380 { 380 {
381 startLandObject = getLandObject(start_x, start_y); 381 startLandObject = getLandObject(start_x, start_y);
382 } 382 }
383 catch (Exception) 383 catch (Exception)
384 { 384 {
385 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + start_x + " y:" + start_y); 385 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + start_x + " y:" + start_y);
386 } 386 }
387 if (startLandObject == null) return false; //No such land object at the beginning 387 if (startLandObject == null) return false; //No such land object at the beginning
388 388
389 //Loop through the points 389 //Loop through the points
390 try 390 try
391 { 391 {
392 int totalX = end_x - start_x; 392 int totalX = end_x - start_x;
393 int totalY = end_y - start_y; 393 int totalY = end_y - start_y;
394 int x, y; 394 int x, y;
395 for (y = 0; y < totalY; y++) 395 for (y = 0; y < totalY; y++)
396 { 396 {
397 for (x = 0; x < totalX; x++) 397 for (x = 0; x < totalX; x++)
398 { 398 {
399 ILandObject tempLandObject = getLandObject(start_x + x, start_y + y); 399 ILandObject tempLandObject = getLandObject(start_x + x, start_y + y);
400 if (tempLandObject == null) return false; //No such land object at that point 400 if (tempLandObject == null) return false; //No such land object at that point
401 if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no 401 if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no
402 } 402 }
403 } 403 }
404 } 404 }
405 catch (Exception) 405 catch (Exception)
406 { 406 {
407 return false; //Exception. For now, lets skip subdivision 407 return false; //Exception. For now, lets skip subdivision
408 } 408 }
409 409
410 //If we are still here, then they are subdividing within one piece of land 410 //If we are still here, then they are subdividing within one piece of land
411 //Check owner 411 //Check owner
412 if (startLandObject.landData.ownerID != attempting_user_id) 412 if (startLandObject.landData.ownerID != attempting_user_id)
413 { 413 {
414 return false; //They cant do this! 414 return false; //They cant do this!
415 } 415 }
416 416
417 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info) 417 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
418 ILandObject newLand = startLandObject.Copy(); 418 ILandObject newLand = startLandObject.Copy();
419 newLand.landData.landName = "Subdivision of " + newLand.landData.landName; 419 newLand.landData.landName = "Subdivision of " + newLand.landData.landName;
420 newLand.landData.globalID = LLUUID.Random(); 420 newLand.landData.globalID = LLUUID.Random();
421 421
422 newLand.setLandBitmap(newLand.getSquareLandBitmap(start_x, start_y, end_x, end_y)); 422 newLand.setLandBitmap(newLand.getSquareLandBitmap(start_x, start_y, end_x, end_y));
423 423
424 //Now, lets set the subdivision area of the original to false 424 //Now, lets set the subdivision area of the original to false
425 int startLandObjectIndex = startLandObject.landData.localID; 425 int startLandObjectIndex = startLandObject.landData.localID;
426 landList[startLandObjectIndex].setLandBitmap( 426 landList[startLandObjectIndex].setLandBitmap(
427 newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); 427 newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false));
428 landList[startLandObjectIndex].forceUpdateLandInfo(); 428 landList[startLandObjectIndex].forceUpdateLandInfo();
429 429
430 setPrimsTainted(); 430 setPrimsTainted();
431 431
432 //Now add the new land object 432 //Now add the new land object
433 ILandObject result = addLandObject(newLand); 433 ILandObject result = addLandObject(newLand);
434 updateLandObject(startLandObject.landData.localID, startLandObject.landData); 434 updateLandObject(startLandObject.landData.localID, startLandObject.landData);
435 result.sendLandUpdateToAvatarsOverMe(); 435 result.sendLandUpdateToAvatarsOverMe();
436 436
437 437
438 return true; 438 return true;
439 } 439 }
440 440
441 /// <summary> 441 /// <summary>
442 /// Join 2 land objects together 442 /// Join 2 land objects together
443 /// </summary> 443 /// </summary>
444 /// <param name="start_x">x value in first piece of land</param> 444 /// <param name="start_x">x value in first piece of land</param>
445 /// <param name="start_y">y value in first piece of land</param> 445 /// <param name="start_y">y value in first piece of land</param>
446 /// <param name="end_x">x value in second peice of land</param> 446 /// <param name="end_x">x value in second peice of land</param>
447 /// <param name="end_y">y value in second peice of land</param> 447 /// <param name="end_y">y value in second peice of land</param>
448 /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param> 448 /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param>
449 /// <returns>Returns true if successful</returns> 449 /// <returns>Returns true if successful</returns>
450 private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) 450 private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
451 { 451 {
452 end_x -= 4; 452 end_x -= 4;
453 end_y -= 4; 453 end_y -= 4;
454 454
455 List<ILandObject> selectedLandObjects = new List<ILandObject>(); 455 List<ILandObject> selectedLandObjects = new List<ILandObject>();
456 int stepXSelected = 0; 456 int stepXSelected = 0;
457 int stepYSelected = 0; 457 int stepYSelected = 0;
458 for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4) 458 for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4)
459 { 459 {
460 for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4) 460 for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4)
461 { 461 {
462 ILandObject p = null; 462 ILandObject p = null;
463 try 463 try
464 { 464 {
465 p = getLandObject(stepXSelected, stepYSelected); 465 p = getLandObject(stepXSelected, stepYSelected);
466 } 466 }
467 catch (Exception) 467 catch (Exception)
468 { 468 {
469 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + stepXSelected + " y:" + stepYSelected); 469 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + stepXSelected + " y:" + stepYSelected);
470 } 470 }
471 if (p != null) 471 if (p != null)
472 { 472 {
473 if (!selectedLandObjects.Contains(p)) 473 if (!selectedLandObjects.Contains(p))
474 { 474 {
475 selectedLandObjects.Add(p); 475 selectedLandObjects.Add(p);
476 } 476 }
477 } 477 }
478 } 478 }
479 } 479 }
480 ILandObject masterLandObject = selectedLandObjects[0]; 480 ILandObject masterLandObject = selectedLandObjects[0];
481 selectedLandObjects.RemoveAt(0); 481 selectedLandObjects.RemoveAt(0);
482 482
483 483
484 if (selectedLandObjects.Count < 1) 484 if (selectedLandObjects.Count < 1)
485 { 485 {
486 return false; //Only one piece of land selected 486 return false; //Only one piece of land selected
487 } 487 }
488 if (masterLandObject.landData.ownerID != attempting_user_id) 488 if (masterLandObject.landData.ownerID != attempting_user_id)
489 { 489 {
490 return false; //Not the same owner 490 return false; //Not the same owner
491 } 491 }
492 foreach (ILandObject p in selectedLandObjects) 492 foreach (ILandObject p in selectedLandObjects)
493 { 493 {
494 if (p.landData.ownerID != masterLandObject.landData.ownerID) 494 if (p.landData.ownerID != masterLandObject.landData.ownerID)
495 { 495 {
496 return false; //Over multiple users. TODO: make this just ignore this piece of land? 496 return false; //Over multiple users. TODO: make this just ignore this piece of land?
497 } 497 }
498 } 498 }
499 foreach (ILandObject slaveLandObject in selectedLandObjects) 499 foreach (ILandObject slaveLandObject in selectedLandObjects)
500 { 500 {
501 landList[masterLandObject.landData.localID].setLandBitmap( 501 landList[masterLandObject.landData.localID].setLandBitmap(
502 slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); 502 slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap()));
503 performFinalLandJoin(masterLandObject, slaveLandObject); 503 performFinalLandJoin(masterLandObject, slaveLandObject);
504 } 504 }
505 505
506 506
507 setPrimsTainted(); 507 setPrimsTainted();
508 508
509 masterLandObject.sendLandUpdateToAvatarsOverMe(); 509 masterLandObject.sendLandUpdateToAvatarsOverMe();
510 510
511 return true; 511 return true;
512 } 512 }
513 513
514 #endregion 514 #endregion
515 515
516 #region Parcel Updating 516 #region Parcel Updating
517 517
518 /// <summary> 518 /// <summary>
519 /// Where we send the ParcelOverlay packet to the client 519 /// Where we send the ParcelOverlay packet to the client
520 /// </summary> 520 /// </summary>
521 /// <param name="remote_client">The object representing the client</param> 521 /// <param name="remote_client">The object representing the client</param>
522 public void sendParcelOverlay(IClientAPI remote_client) 522 public void sendParcelOverlay(IClientAPI remote_client)
523 { 523 {
524 const int LAND_BLOCKS_PER_PACKET = 1024; 524 const int LAND_BLOCKS_PER_PACKET = 1024;
525 int x, y = 0; 525 int x, y = 0;
526 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 526 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
527 int byteArrayCount = 0; 527 int byteArrayCount = 0;
528 int sequenceID = 0; 528 int sequenceID = 0;
529 ParcelOverlayPacket packet; 529 ParcelOverlayPacket packet;
530 530
531 for (y = 0; y < 64; y++) 531 for (y = 0; y < 64; y++)
532 { 532 {
533 for (x = 0; x < 64; x++) 533 for (x = 0; x < 64; x++)
534 { 534 {
535 byte tempByte = (byte) 0; //This represents the byte for the current 4x4 535 byte tempByte = (byte) 0; //This represents the byte for the current 4x4
536 ILandObject currentParcelBlock = null; 536 ILandObject currentParcelBlock = null;
537 537
538 try 538 try
539 { 539 {
540 currentParcelBlock = getLandObject(x * 4, y * 4); 540 currentParcelBlock = getLandObject(x * 4, y * 4);
541 } 541 }
542 catch (Exception) 542 catch (Exception)
543 { 543 {
544 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (x * 4) + " y: " + (y * 4)); 544 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (x * 4) + " y: " + (y * 4));
545 } 545 }
546 546
547 547
548 if (currentParcelBlock != null) 548 if (currentParcelBlock != null)
549 { 549 {
550 if (currentParcelBlock.landData.ownerID == remote_client.AgentId) 550 if (currentParcelBlock.landData.ownerID == remote_client.AgentId)
551 { 551 {
552 //Owner Flag 552 //Owner Flag
553 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER); 553 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER);
554 } 554 }
555 else if (currentParcelBlock.landData.salePrice > 0 && 555 else if (currentParcelBlock.landData.salePrice > 0 &&
556 (currentParcelBlock.landData.authBuyerID == LLUUID.Zero || 556 (currentParcelBlock.landData.authBuyerID == LLUUID.Zero ||
557 currentParcelBlock.landData.authBuyerID == remote_client.AgentId)) 557 currentParcelBlock.landData.authBuyerID == remote_client.AgentId))
558 { 558 {
559 //Sale Flag 559 //Sale Flag
560 tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE); 560 tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE);
561 } 561 }
562 else if (currentParcelBlock.landData.ownerID == LLUUID.Zero) 562 else if (currentParcelBlock.landData.ownerID == LLUUID.Zero)
563 { 563 {
564 //Public Flag 564 //Public Flag
565 tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC); 565 tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC);
566 } 566 }
567 else 567 else
568 { 568 {
569 //Other Flag 569 //Other Flag
570 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER); 570 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER);
571 } 571 }
572 572
573 573
574 //Now for border control 574 //Now for border control
575 try 575 try
576 { 576 {
577 ILandObject westParcel = null; 577 ILandObject westParcel = null;
578 ILandObject southParcel = null; 578 ILandObject southParcel = null;
579 if (x > 0) 579 if (x > 0)
580 { 580 {
581 westParcel = getLandObject((x - 1) * 4, y * 4); 581 westParcel = getLandObject((x - 1) * 4, y * 4);
582 } 582 }
583 if (y > 0) 583 if (y > 0)
584 { 584 {
585 southParcel = getLandObject(x * 4, (y - 1) * 4); 585 southParcel = getLandObject(x * 4, (y - 1) * 4);
586 } 586 }
587 587
588 if (x == 0) 588 if (x == 0)
589 { 589 {
590 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); 590 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST);
591 } 591 }
592 else if (westParcel != null && westParcel != currentParcelBlock) 592 else if (westParcel != null && westParcel != currentParcelBlock)
593 { 593 {
594 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); 594 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST);
595 } 595 }
596 596
597 if (y == 0) 597 if (y == 0)
598 { 598 {
599 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); 599 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH);
600 } 600 }
601 else if (southParcel != null && southParcel != currentParcelBlock) 601 else if (southParcel != null && southParcel != currentParcelBlock)
602 { 602 {
603 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); 603 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH);
604 } 604 }
605 605
606 byteArray[byteArrayCount] = tempByte; 606 byteArray[byteArrayCount] = tempByte;
607 byteArrayCount++; 607 byteArrayCount++;
608 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) 608 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
609 { 609 {
610 byteArrayCount = 0; 610 byteArrayCount = 0;
611 packet = (ParcelOverlayPacket) PacketPool.Instance.GetPacket(PacketType.ParcelOverlay); 611 packet = (ParcelOverlayPacket) PacketPool.Instance.GetPacket(PacketType.ParcelOverlay);
612 packet.ParcelData.Data = byteArray; 612 packet.ParcelData.Data = byteArray;
613 packet.ParcelData.SequenceID = sequenceID; 613 packet.ParcelData.SequenceID = sequenceID;
614 remote_client.OutPacket((Packet) packet, ThrottleOutPacketType.Task); 614 remote_client.OutPacket((Packet) packet, ThrottleOutPacketType.Task);
615 sequenceID++; 615 sequenceID++;
616 byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 616 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
617 } 617 }
618 } 618 }
619 catch (Exception) 619 catch (Exception)
620 { 620 {
621 //m_log.Debug("[LAND]: Skipped Land checks because avatar is out of bounds: " + e.Message); 621 //m_log.Debug("[LAND]: Skipped Land checks because avatar is out of bounds: " + e.Message);
622 } 622 }
623 } 623 }
624 } 624 }
625 } 625 }
626 } 626 }
627 627
628 public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, 628 public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
629 bool snap_selection, IClientAPI remote_client) 629 bool snap_selection, IClientAPI remote_client)
630 { 630 {
631 //Get the land objects within the bounds 631 //Get the land objects within the bounds
632 List<ILandObject> temp = new List<ILandObject>(); 632 List<ILandObject> temp = new List<ILandObject>();
633 int x, y, i; 633 int x, y, i;
634 int inc_x = end_x - start_x; 634 int inc_x = end_x - start_x;
635 int inc_y = end_y - start_y; 635 int inc_y = end_y - start_y;
636 for (x = 0; x < inc_x; x++) 636 for (x = 0; x < inc_x; x++)
637 { 637 {
638 for (y = 0; y < inc_y; y++) 638 for (y = 0; y < inc_y; y++)
639 { 639 {
640 ILandObject currentParcel = null; 640 ILandObject currentParcel = null;
641 try 641 try
642 { 642 {
643 currentParcel = getLandObject(start_x + x, start_y + y); 643 currentParcel = getLandObject(start_x + x, start_y + y);
644 } 644 }
645 catch (Exception) 645 catch (Exception)
646 { 646 {
647 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (start_x + x) + " y: " + (start_y + y)); 647 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (start_x + x) + " y: " + (start_y + y));
648 } 648 }
649 if (currentParcel != null) 649 if (currentParcel != null)
650 { 650 {
651 if (!temp.Contains(currentParcel)) 651 if (!temp.Contains(currentParcel))
652 { 652 {
653 currentParcel.forceUpdateLandInfo(); 653 currentParcel.forceUpdateLandInfo();
654 temp.Add(currentParcel); 654 temp.Add(currentParcel);
655 } 655 }
656 } 656 }
657 } 657 }
658 } 658 }
659 659
660 int requestResult = LAND_RESULT_SINGLE; 660 int requestResult = LAND_RESULT_SINGLE;
661 if (temp.Count > 1) 661 if (temp.Count > 1)
662 { 662 {
663 requestResult = LAND_RESULT_MULTIPLE; 663 requestResult = LAND_RESULT_MULTIPLE;
664 } 664 }
665 665
666 for (i = 0; i < temp.Count; i++) 666 for (i = 0; i < temp.Count; i++)
667 { 667 {
668 temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client); 668 temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client);
669 } 669 }
670 670
671 671
672 sendParcelOverlay(remote_client); 672 sendParcelOverlay(remote_client);
673 } 673 }
674 674
675 public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) 675 public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
676 { 676 {
677 if (landList.ContainsKey(packet.ParcelData.LocalID)) 677 if (landList.ContainsKey(packet.ParcelData.LocalID))
678 { 678 {
679 landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client); 679 landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client);
680 } 680 }
681 } 681 }
682 682
683 public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) 683 public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
684 { 684 {
685 subdivide(west, south, east, north, remote_client.AgentId); 685 subdivide(west, south, east, north, remote_client.AgentId);
686 } 686 }
687 687
688 public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client) 688 public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client)
689 { 689 {
690 join(west, south, east, north, remote_client.AgentId); 690 join(west, south, east, north, remote_client.AgentId);
691 } 691 }
692 692
693 public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) 693 public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client)
694 { 694 {
695 landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); 695 landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client);
696 } 696 }
697 697
698 public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) 698 public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client)
699 { 699 {
700 landList[local_id].sendLandObjectOwners(remote_client); 700 landList[local_id].sendLandObjectOwners(remote_client);
701 } 701 }
702 702
703 #endregion 703 #endregion
704 704
705 #region ILandChannel Members 705 #region ILandChannel Members
706 706
707 public bool allowedForcefulBans 707 public bool allowedForcefulBans
708 { 708 {
709 get { return m_allowedForcefulBans; } 709 get { return m_allowedForcefulBans; }
710 set { m_allowedForcefulBans = value; } 710 set { m_allowedForcefulBans = value; }
711 } 711 }
712 712
713 /// <summary> 713 /// <summary>
714 /// Resets the sim to the default land object (full sim piece of land owned by the default user) 714 /// Resets the sim to the default land object (full sim piece of land owned by the default user)
715 /// </summary> 715 /// </summary>
716 public void resetSimLandObjects() 716 public void resetSimLandObjects()
717 { 717 {
718 //Remove all the land objects in the sim and add a blank, full sim land object set to public 718 //Remove all the land objects in the sim and add a blank, full sim land object set to public
719 landList.Clear(); 719 landList.Clear();
720 lastLandLocalID = START_LAND_LOCAL_ID - 1; 720 lastLandLocalID = START_LAND_LOCAL_ID - 1;
721 landIDList.Initialize(); 721 landIDList.Initialize();
722 722
723 ILandObject fullSimParcel = new LandObject(LLUUID.Zero, false, m_scene); 723 ILandObject fullSimParcel = new LandObject(LLUUID.Zero, false, m_scene);
724 724
725 fullSimParcel.setLandBitmap(fullSimParcel.getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize)); 725 fullSimParcel.setLandBitmap(fullSimParcel.getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize));
726 fullSimParcel.landData.ownerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; 726 fullSimParcel.landData.ownerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
727 727
728 addLandObject(fullSimParcel); 728 addLandObject(fullSimParcel);
729 } 729 }
730 730
731 public List<ILandObject> parcelsNearPoint(LLVector3 position) 731 public List<ILandObject> parcelsNearPoint(LLVector3 position)
732 { 732 {
733 List<ILandObject> parcelsNear = new List<ILandObject>(); 733 List<ILandObject> parcelsNear = new List<ILandObject>();
734 int x, y; 734 int x, y;
735 for (x = -4; x <= 4; x += 4) 735 for (x = -4; x <= 4; x += 4)
736 { 736 {
737 for (y = -4; y <= 4; y += 4) 737 for (y = -4; y <= 4; y += 4)
738 { 738 {
739 ILandObject check = getLandObject(position.X + x, position.Y + y); 739 ILandObject check = getLandObject(position.X + x, position.Y + y);
740 if (check != null) 740 if (check != null)
741 { 741 {
742 if (!parcelsNear.Contains(check)) 742 if (!parcelsNear.Contains(check))
743 { 743 {
744 parcelsNear.Add(check); 744 parcelsNear.Add(check);
745 } 745 }
746 } 746 }
747 } 747 }
748 } 748 }
749 749
750 return parcelsNear; 750 return parcelsNear;
751 } 751 }
752 752
753 public void sendYouAreBannedNotice(ScenePresence avatar) 753 public void sendYouAreBannedNotice(ScenePresence avatar)
754 { 754 {
755 if (allowedForcefulBans) 755 if (allowedForcefulBans)
756 { 756 {
757 avatar.ControllingClient.SendAlertMessage( 757 avatar.ControllingClient.SendAlertMessage(
758 "You are not allowed on this parcel because you are banned. Please go away. <3 OpenSim Developers"); 758 "You are not allowed on this parcel because you are banned. Please go away. <3 OpenSim Developers");
759 759
760 avatar.PhysicsActor.Position = 760 avatar.PhysicsActor.Position =
761 new PhysicsVector(avatar.lastKnownAllowedPosition.x, avatar.lastKnownAllowedPosition.y, 761 new PhysicsVector(avatar.lastKnownAllowedPosition.x, avatar.lastKnownAllowedPosition.y,
762 avatar.lastKnownAllowedPosition.z); 762 avatar.lastKnownAllowedPosition.z);
763 avatar.PhysicsActor.Velocity = new PhysicsVector(0, 0, 0); 763 avatar.PhysicsActor.Velocity = new PhysicsVector(0, 0, 0);
764 } 764 }
765 else 765 else
766 { 766 {
767 avatar.ControllingClient.SendAlertMessage( 767 avatar.ControllingClient.SendAlertMessage(
768 "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! <3 OpenSim Developers"); 768 "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! <3 OpenSim Developers");
769 } 769 }
770 } 770 }
771 771
772 public void handleAvatarChangingParcel(ScenePresence avatar, int localLandID, LLUUID regionID) 772 public void handleAvatarChangingParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
773 { 773 {
774 if (m_scene.RegionInfo.RegionID == regionID) 774 if (m_scene.RegionInfo.RegionID == regionID)
775 { 775 {
776 if (landList[localLandID] != null) 776 if (landList[localLandID] != null)
777 { 777 {
778 ILandObject parcelAvatarIsEntering = landList[localLandID]; 778 ILandObject parcelAvatarIsEntering = landList[localLandID];
779 if (avatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT) 779 if (avatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT)
780 { 780 {
781 if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID)) 781 if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID))
782 { 782 {
783 sendYouAreBannedNotice(avatar); 783 sendYouAreBannedNotice(avatar);
784 } 784 }
785 else if (parcelAvatarIsEntering.isRestrictedFromLand(avatar.UUID)) 785 else if (parcelAvatarIsEntering.isRestrictedFromLand(avatar.UUID))
786 { 786 {
787 avatar.ControllingClient.SendAlertMessage( 787 avatar.ControllingClient.SendAlertMessage(
788 "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!). <3 OpenSim Developers"); 788 "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!). <3 OpenSim Developers");
789 } 789 }
790 else 790 else
791 { 791 {
792 avatar.sentMessageAboutRestrictedParcelFlyingDown = true; 792 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
793 } 793 }
794 } 794 }
795 else 795 else
796 { 796 {
797 avatar.sentMessageAboutRestrictedParcelFlyingDown = true; 797 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
798 } 798 }
799 } 799 }
800 } 800 }
801 } 801 }
802 802
803 public void sendOutNearestBanLine(IClientAPI avatar) 803 public void sendOutNearestBanLine(IClientAPI avatar)
804 { 804 {
805 List<ScenePresence> avatars = m_scene.GetAvatars(); 805 List<ScenePresence> avatars = m_scene.GetAvatars();
806 foreach (ScenePresence presence in avatars) 806 foreach (ScenePresence presence in avatars)
807 { 807 {
808 if (presence.UUID == avatar.AgentId) 808 if (presence.UUID == avatar.AgentId)
809 { 809 {
810 List<ILandObject> checkLandParcels = parcelsNearPoint(presence.AbsolutePosition); 810 List<ILandObject> checkLandParcels = parcelsNearPoint(presence.AbsolutePosition);
811 foreach (ILandObject checkBan in checkLandParcels) 811 foreach (ILandObject checkBan in checkLandParcels)
812 { 812 {
813 if (checkBan.isBannedFromLand(avatar.AgentId)) 813 if (checkBan.isBannedFromLand(avatar.AgentId))
814 { 814 {
815 checkBan.sendLandProperties(-30000, false, (int) ParcelManager.ParcelResult.Single, avatar); 815 checkBan.sendLandProperties(-30000, false, (int) ParcelManager.ParcelResult.Single, avatar);
816 return; //Only send one 816 return; //Only send one
817 } 817 }
818 else if (checkBan.isRestrictedFromLand(avatar.AgentId)) 818 else if (checkBan.isRestrictedFromLand(avatar.AgentId))
819 { 819 {
820 checkBan.sendLandProperties(-40000, false, (int) ParcelManager.ParcelResult.Single, avatar); 820 checkBan.sendLandProperties(-40000, false, (int) ParcelManager.ParcelResult.Single, avatar);
821 return; //Only send one 821 return; //Only send one
822 } 822 }
823 } 823 }
824 return; 824 return;
825 } 825 }
826 } 826 }
827 } 827 }
828 828
829 public void sendLandUpdate(ScenePresence avatar, bool force) 829 public void sendLandUpdate(ScenePresence avatar, bool force)
830 { 830 {
831 ILandObject over = null; 831 ILandObject over = null;
832 try 832 try
833 { 833 {
834 over = getLandObject((int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 834 over = getLandObject((int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
835 (int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 835 (int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
836 } 836 }
837 catch (Exception) 837 catch (Exception)
838 { 838 {
839 //m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + Math.Round(avatar.AbsolutePosition.Y)); 839 //m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + Math.Round(avatar.AbsolutePosition.Y));
840 } 840 }
841 841
842 if (over != null) 842 if (over != null)
843 { 843 {
844 if (force) 844 if (force)
845 { 845 {
846 if (!avatar.IsChildAgent) 846 if (!avatar.IsChildAgent)
847 { 847 {
848 over.sendLandUpdateToClient(avatar.ControllingClient); 848 over.sendLandUpdateToClient(avatar.ControllingClient);
849 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID, 849 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID,
850 m_scene.RegionInfo.RegionID); 850 m_scene.RegionInfo.RegionID);
851 } 851 }
852 } 852 }
853 853
854 if (avatar.currentParcelUUID != over.landData.globalID) 854 if (avatar.currentParcelUUID != over.landData.globalID)
855 { 855 {
856 if (!avatar.IsChildAgent) 856 if (!avatar.IsChildAgent)
857 { 857 {
858 over.sendLandUpdateToClient(avatar.ControllingClient); 858 over.sendLandUpdateToClient(avatar.ControllingClient);
859 avatar.currentParcelUUID = over.landData.globalID; 859 avatar.currentParcelUUID = over.landData.globalID;
860 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID, 860 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID,
861 m_scene.RegionInfo.RegionID); 861 m_scene.RegionInfo.RegionID);
862 } 862 }
863 } 863 }
864 } 864 }
865 } 865 }
866 866
867 public void sendLandUpdate(ScenePresence avatar) 867 public void sendLandUpdate(ScenePresence avatar)
868 { 868 {
869 sendLandUpdate(avatar, false); 869 sendLandUpdate(avatar, false);
870 } 870 }
871 871
872 public void handleSignificantClientMovement(IClientAPI remote_client) 872 public void handleSignificantClientMovement(IClientAPI remote_client)
873 { 873 {
874 ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId); 874 ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId);
875 875
876 if (clientAvatar != null) 876 if (clientAvatar != null)
877 { 877 {
878 sendLandUpdate(clientAvatar); 878 sendLandUpdate(clientAvatar);
879 sendOutNearestBanLine(remote_client); 879 sendOutNearestBanLine(remote_client);
880 ILandObject parcel = getLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); 880 ILandObject parcel = getLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
881 if (parcel != null) 881 if (parcel != null)
882 { 882 {
883 if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT && 883 if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT &&
884 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) 884 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown)
885 { 885 {
886 handleAvatarChangingParcel(clientAvatar, parcel.landData.localID, m_scene.RegionInfo.RegionID); 886 handleAvatarChangingParcel(clientAvatar, parcel.landData.localID, m_scene.RegionInfo.RegionID);
887 //They are going below the safety line! 887 //They are going below the safety line!
888 if (!parcel.isBannedFromLand(clientAvatar.UUID)) 888 if (!parcel.isBannedFromLand(clientAvatar.UUID))
889 { 889 {
890 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; 890 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
891 } 891 }
892 } 892 }
893 else if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT && 893 else if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT &&
894 parcel.isBannedFromLand(clientAvatar.UUID)) 894 parcel.isBannedFromLand(clientAvatar.UUID))
895 { 895 {
896 sendYouAreBannedNotice(clientAvatar); 896 sendYouAreBannedNotice(clientAvatar);
897 } 897 }
898 } 898 }
899 } 899 }
900 } 900 }
901 901
902 public void handleAnyClientMovement(ScenePresence avatar) 902 public void handleAnyClientMovement(ScenePresence avatar)
903 //Like handleSignificantClientMovement, but called with an AgentUpdate regardless of distance. 903 //Like handleSignificantClientMovement, but called with an AgentUpdate regardless of distance.
904 { 904 {
905 ILandObject over = getLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 905 ILandObject over = getLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
906 if (over != null) 906 if (over != null)
907 { 907 {
908 if (!over.isBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= BAN_LINE_SAFETY_HIEGHT) 908 if (!over.isBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= BAN_LINE_SAFETY_HIEGHT)
909 { 909 {
910 avatar.lastKnownAllowedPosition = 910 avatar.lastKnownAllowedPosition =
911 new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); 911 new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
912 } 912 }
913 } 913 }
914 } 914 }
915 915
916 916
917 public void handleParcelAccessRequest(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, 917 public void handleParcelAccessRequest(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID,
918 int landLocalID, IClientAPI remote_client) 918 int landLocalID, IClientAPI remote_client)
919 { 919 {
920 if (landList.ContainsKey(landLocalID)) 920 if (landList.ContainsKey(landLocalID))
921 { 921 {
922 landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client); 922 landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client);
923 } 923 }
924 } 924 }
925 925
926 public void handleParcelAccessUpdateRequest(LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID, 926 public void handleParcelAccessUpdateRequest(LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID,
927 List<ParcelManager.ParcelAccessEntry> entries, 927 List<ParcelManager.ParcelAccessEntry> entries,
928 IClientAPI remote_client) 928 IClientAPI remote_client)
929 { 929 {
930 if (landList.ContainsKey(landLocalID)) 930 if (landList.ContainsKey(landLocalID))
931 { 931 {
932 if (agentID == landList[landLocalID].landData.ownerID) 932 if (agentID == landList[landLocalID].landData.ownerID)
933 { 933 {
934 landList[landLocalID].updateAccessList(flags, entries, remote_client); 934 landList[landLocalID].updateAccessList(flags, entries, remote_client);
935 } 935 }
936 } 936 }
937 else 937 else
938 { 938 {
939 Console.WriteLine("INVALID LOCAL LAND ID"); 939 Console.WriteLine("INVALID LOCAL LAND ID");
940 } 940 }
941 } 941 }
942 942
943 #endregion 943 #endregion
944 944
945 // If the economy has been validated by the economy module, 945 // If the economy has been validated by the economy module,
946 // and land has been validated as well, this method transfers 946 // and land has been validated as well, this method transfers
947 // the land ownership 947 // the land ownership
948 948
949 public void handleLandBuyRequest(Object o, EventManager.LandBuyArgs e) 949 public void handleLandBuyRequest(Object o, EventManager.LandBuyArgs e)
950 { 950 {
951 if (e.economyValidated && e.landValidated) 951 if (e.economyValidated && e.landValidated)
952 { 952 {
953 lock (landList) 953 lock (landList)
954 { 954 {
955 if (landList.ContainsKey(e.parcelLocalID)) 955 if (landList.ContainsKey(e.parcelLocalID))
956 { 956 {
957 landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint) e.transactionID, e.parcelPrice, e.parcelArea); 957 landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint) e.transactionID, e.parcelPrice, e.parcelArea);
958 return; 958 return;
959 } 959 }
960 } 960 }
961 } 961 }
962 } 962 }
963 963
964 // After receiving a land buy packet, first the data needs to 964 // After receiving a land buy packet, first the data needs to
965 // be validated. This method validates the right to buy the 965 // be validated. This method validates the right to buy the
966 // parcel 966 // parcel
967 967
968 public void handleLandValidationRequest(Object o, EventManager.LandBuyArgs e) 968 public void handleLandValidationRequest(Object o, EventManager.LandBuyArgs e)
969 { 969 {
970 if (e.landValidated == false) 970 if (e.landValidated == false)
971 { 971 {
972 ILandObject lob = null; 972 ILandObject lob = null;
973 lock (landList) 973 lock (landList)
974 { 974 {
975 if (landList.ContainsKey(e.parcelLocalID)) 975 if (landList.ContainsKey(e.parcelLocalID))
976 { 976 {
977 lob = landList[e.parcelLocalID]; 977 lob = landList[e.parcelLocalID];
978 } 978 }
979 } 979 }
980 if (lob != null) 980 if (lob != null)
981 { 981 {
982 LLUUID AuthorizedID = lob.landData.authBuyerID; 982 LLUUID AuthorizedID = lob.landData.authBuyerID;
983 int saleprice = lob.landData.salePrice; 983 int saleprice = lob.landData.salePrice;
984 LLUUID pOwnerID = lob.landData.ownerID; 984 LLUUID pOwnerID = lob.landData.ownerID;
985 985
986 bool landforsale = ((lob.landData.landFlags & 986 bool landforsale = ((lob.landData.landFlags &
987 (uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0); 987 (uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0);
988 if ((AuthorizedID == LLUUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale) 988 if ((AuthorizedID == LLUUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale)
989 { 989 {
990 lock (e) 990 lock (e)
991 { 991 {
992 e.parcelOwnerID = pOwnerID; 992 e.parcelOwnerID = pOwnerID;
993 e.landValidated = true; 993 e.landValidated = true;
994 } 994 }
995 } 995 }
996 } 996 }
997 } 997 }
998 } 998 }
999 } 999 }
1000} \ No newline at end of file 1000} \ No newline at end of file