aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authormingchen2007-07-16 18:45:19 +0000
committermingchen2007-07-16 18:45:19 +0000
commit7fabf9612a539e96c67a7e6a460f200d20cfeff6 (patch)
tree45a10ed5ba61dfc1d96d9840e1fbef84c195edfd
parent* Since we're discussing it, applying the m_ convention on some members... (diff)
downloadopensim-SC_OLD-7fabf9612a539e96c67a7e6a460f200d20cfeff6.zip
opensim-SC_OLD-7fabf9612a539e96c67a7e6a460f200d20cfeff6.tar.gz
opensim-SC_OLD-7fabf9612a539e96c67a7e6a460f200d20cfeff6.tar.bz2
opensim-SC_OLD-7fabf9612a539e96c67a7e6a460f200d20cfeff6.tar.xz
*Renamed ParcelManager to LandManager
*Made the Parcel class its own file and moved the Parcel and LandManager into their own folder in Environment *Some renaming might need to be done so the Parcel class doesn't have issues with the libsecondlife Parcel class, but Land doesn't seem right.
-rw-r--r--OpenSim/Region/Application/OpenSimMain.cs4
-rw-r--r--OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs5
-rw-r--r--OpenSim/Region/Environment/ParcelManager.cs1206
-rw-r--r--OpenSim/Region/Environment/Parcels/Parcel.cs599
-rw-r--r--OpenSim/Region/Environment/RegionManager.cs3
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs4
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs42
-rw-r--r--OpenSim/Region/Examples/SimpleApp/Program.cs2
-rw-r--r--OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs6
9 files changed, 634 insertions, 1237 deletions
diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs
index 05ccbc3..4e10955 100644
--- a/OpenSim/Region/Application/OpenSimMain.cs
+++ b/OpenSim/Region/Application/OpenSimMain.cs
@@ -240,13 +240,13 @@ namespace OpenSim
240 { 240 {
241 m_log.Notice("Parcels - Found master avatar [" + masterAvatar.UUID.ToStringHyphenated() + "]"); 241 m_log.Notice("Parcels - Found master avatar [" + masterAvatar.UUID.ToStringHyphenated() + "]");
242 scene.RegionInfo.MasterAvatarAssignedUUID = masterAvatar.UUID; 242 scene.RegionInfo.MasterAvatarAssignedUUID = masterAvatar.UUID;
243 scene.localStorage.LoadParcels((ILocalStorageParcelReceiver)scene.ParcelManager); 243 scene.localStorage.LoadParcels((ILocalStorageParcelReceiver)scene.LandManager);
244 } 244 }
245 else 245 else
246 { 246 {
247 m_log.Notice("Parcels - No master avatar found, using null."); 247 m_log.Notice("Parcels - No master avatar found, using null.");
248 scene.RegionInfo.MasterAvatarAssignedUUID = libsecondlife.LLUUID.Zero; 248 scene.RegionInfo.MasterAvatarAssignedUUID = libsecondlife.LLUUID.Zero;
249 scene.localStorage.LoadParcels((ILocalStorageParcelReceiver)scene.ParcelManager); 249 scene.localStorage.LoadParcels((ILocalStorageParcelReceiver)scene.LandManager);
250 } 250 }
251 scene.performParcelPrimCountUpdate(); 251 scene.performParcelPrimCountUpdate();
252 scene.StartTimer(); 252 scene.StartTimer();
diff --git a/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs
index 6ee57a5..05e936e 100644
--- a/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs
+++ b/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs
@@ -32,6 +32,7 @@ using OpenSim.Framework.Types;
32using OpenSim.Region; 32using OpenSim.Region;
33using OpenSim.Region.Environment; 33using OpenSim.Region.Environment;
34using OpenSim.Region.Environment.Scenes; 34using OpenSim.Region.Environment.Scenes;
35using OpenSim.Region.Environment.Parcels;
35 36
36using System.Collections.Generic; 37using System.Collections.Generic;
37 38
@@ -54,9 +55,9 @@ namespace OpenSim.Region.Interfaces
54 void StoreTerrain(double[,] terrain); 55 void StoreTerrain(double[,] terrain);
55 double[,] LoadTerrain(); 56 double[,] LoadTerrain();
56 57
57 void StoreParcel(OpenSim.Region.Environment.Parcel Parcel); 58 void StoreParcel(Environment.Parcels.Parcel Parcel);
58 void RemoveParcel(uint ID); 59 void RemoveParcel(uint ID);
59 List<OpenSim.Region.Environment.Parcel> LoadParcels(); 60 List<Environment.Parcels.Parcel> LoadParcels();
60 61
61 void Shutdown(); 62 void Shutdown();
62 } 63 }
diff --git a/OpenSim/Region/Environment/ParcelManager.cs b/OpenSim/Region/Environment/ParcelManager.cs
deleted file mode 100644
index fbff556..0000000
--- a/OpenSim/Region/Environment/ParcelManager.cs
+++ /dev/null
@@ -1,1206 +0,0 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Collections.Generic;
30using libsecondlife;
31using libsecondlife.Packets;
32using OpenSim.Framework.Interfaces;
33using OpenSim.Framework.Types;
34using OpenSim.Region.Environment.Scenes;
35using Avatar = OpenSim.Region.Environment.Scenes.ScenePresence;
36using System.IO;
37
38namespace OpenSim.Region.Environment
39{
40
41
42 #region ParcelManager Class
43 /// <summary>
44 /// Handles Parcel objects and operations requiring information from other Parcel objects (divide, join, etc)
45 /// </summary>
46 public class ParcelManager : ILocalStorageParcelReceiver
47 {
48
49 #region Constants
50 //Parcel types set with flags in ParcelOverlay.
51 //Only one of these can be used.
52 public const byte PARCEL_TYPE_PUBLIC = (byte)0; //Equals 00000000
53 public const byte PARCEL_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001
54 public const byte PARCEL_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010
55 public const byte PARCEL_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011
56 public const byte PARCEL_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100
57 public const byte PARCEL_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101
58
59
60 //Flags that when set, a border on the given side will be placed
61 //NOTE: North and East is assumable by the west and south sides (if parcel to east has a west border, then I have an east border; etc)
62 //This took forever to figure out -- jeesh. /blame LL for even having to send these
63 public const byte PARCEL_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000
64 public const byte PARCEL_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000
65
66 //RequestResults (I think these are right, they seem to work):
67 public const int PARCEL_RESULT_ONE_PARCEL = 0; // The request they made contained only one parcel
68 public const int PARCEL_RESULT_MULTIPLE_PARCELS = 1; // The request they made contained more than one parcel
69
70 //ParcelSelectObjects
71 public const int PARCEL_SELECT_OBJECTS_OWNER = 2;
72 public const int PARCEL_SELECT_OBJECTS_GROUP = 4;
73 public const int PARCEL_SELECT_OBJECTS_OTHER = 8;
74
75
76 //These are other constants. Yay!
77 public const int START_PARCEL_LOCAL_ID = 1;
78 #endregion
79
80 #region Member Variables
81 public Dictionary<int, Parcel> parcelList = new Dictionary<int, Parcel>();
82 private int lastParcelLocalID = START_PARCEL_LOCAL_ID - 1;
83 private int[,] parcelIDList = new int[64, 64];
84
85 /// <summary>
86 /// Set to true when a prim is moved, created, added. Performs a prim count update
87 /// </summary>
88 public bool parcelPrimCountTainted = false;
89
90 private Scene m_world;
91 private RegionInfo m_regInfo;
92
93 #endregion
94
95 #region Constructors
96 public ParcelManager(Scene world, RegionInfo reginfo)
97 {
98
99 m_world = world;
100 m_regInfo = reginfo;
101 parcelIDList.Initialize();
102
103 }
104 #endregion
105
106 #region Member Functions
107
108 #region Parcel From Storage Functions
109 public void ParcelFromStorage(ParcelData data)
110 {
111 Parcel new_parcel = new Parcel(data.ownerID, data.isGroupOwned, m_world);
112 new_parcel.parcelData = data.Copy();
113 new_parcel.setParcelBitmapFromByteArray();
114 addParcel(new_parcel);
115
116 }
117
118 public void NoParcelDataFromStorage()
119 {
120 resetSimParcels();
121 }
122 #endregion
123
124 #region Parcel Add/Remove/Get/Create
125 /// <summary>
126 /// Creates a basic Parcel object without an owner (a zeroed key)
127 /// </summary>
128 /// <returns></returns>
129 public Parcel createBaseParcel()
130 {
131 return new Parcel(new LLUUID(), false, m_world);
132 }
133
134 /// <summary>
135 /// Adds a parcel to the stored list and adds them to the parcelIDList to what they own
136 /// </summary>
137 /// <param name="new_parcel">The parcel being added</param>
138 public Parcel addParcel(Parcel new_parcel)
139 {
140 lastParcelLocalID++;
141 new_parcel.parcelData.localID = lastParcelLocalID;
142 parcelList.Add(lastParcelLocalID, new_parcel.Copy());
143
144
145 bool[,] parcelBitmap = new_parcel.getParcelBitmap();
146 int x, y;
147 for (x = 0; x < 64; x++)
148 {
149 for (y = 0; y < 64; y++)
150 {
151 if (parcelBitmap[x, y])
152 {
153 parcelIDList[x, y] = lastParcelLocalID;
154 }
155 }
156 }
157 parcelList[lastParcelLocalID].forceUpdateParcelInfo();
158
159 return new_parcel;
160
161 }
162 /// <summary>
163 /// Removes a parcel from the list. Will not remove if local_id is still owning an area in parcelIDList
164 /// </summary>
165 /// <param name="local_id">Parcel.localID of the parcel to remove.</param>
166 public void removeParcel(int local_id)
167 {
168 int x, y;
169 for (x = 0; x < 64; x++)
170 {
171 for (y = 0; y < 64; y++)
172 {
173 if (parcelIDList[x, y] == local_id)
174 {
175 throw new Exception("Could not remove parcel. Still being used at " + x + ", " + y);
176 }
177 }
178 }
179 m_world.localStorage.RemoveParcel(parcelList[local_id].parcelData);
180 parcelList.Remove(local_id);
181 }
182
183 private void performFinalParcelJoin(Parcel master, Parcel slave)
184 {
185 int x, y;
186 bool[,] parcelBitmapSlave = slave.getParcelBitmap();
187 for (x = 0; x < 64; x++)
188 {
189 for (y = 0; y < 64; y++)
190 {
191 if (parcelBitmapSlave[x, y])
192 {
193 parcelIDList[x, y] = master.parcelData.localID;
194 }
195 }
196 }
197 removeParcel(slave.parcelData.localID);
198 }
199 /// <summary>
200 /// Get the parcel at the specified point
201 /// </summary>
202 /// <param name="x">Value between 0 - 256 on the x axis of the point</param>
203 /// <param name="y">Value between 0 - 256 on the y axis of the point</param>
204 /// <returns>Parcel at the point supplied</returns>
205 public Parcel getParcel(float x_float, float y_float)
206 {
207 int x = Convert.ToInt32(Math.Floor(Convert.ToDecimal(x_float) / Convert.ToDecimal(4.0)));
208 int y = Convert.ToInt32(Math.Floor(Convert.ToDecimal(y_float) / Convert.ToDecimal(4.0)));
209
210 if (x > 63 || y > 63 || x < 0 || y < 0)
211 {
212 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
213 }
214 else
215 {
216 // Console.WriteLine("Point (" + x + ", " + y + ") determined from point (" + x_float + ", " + y_float + ")");
217 return parcelList[parcelIDList[x, y]];
218 }
219 }
220
221 public Parcel getParcel(int x, int y)
222 {
223 if (x > 256 || y > 256 || x < 0 || y < 0)
224 {
225 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
226 }
227 else
228 {
229 return parcelList[parcelIDList[x / 4, y / 4]];
230 }
231 }
232 #endregion
233
234 #region Parcel Modification
235 /// <summary>
236 /// Subdivides a parcel
237 /// </summary>
238 /// <param name="start_x">West Point</param>
239 /// <param name="start_y">South Point</param>
240 /// <param name="end_x">East Point</param>
241 /// <param name="end_y">North Point</param>
242 /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param>
243 /// <returns>Returns true if successful</returns>
244 private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
245 {
246
247 //First, lets loop through the points and make sure they are all in the same parcel
248 //Get the parcel at start
249 Parcel startParcel = getParcel(start_x, start_y);
250 if (startParcel == null) return false; //No such parcel at the beginning
251
252 //Loop through the points
253 try
254 {
255 int totalX = end_x - start_x;
256 int totalY = end_y - start_y;
257 int x, y;
258 for (y = 0; y < totalY; y++)
259 {
260 for (x = 0; x < totalX; x++)
261 {
262 Parcel tempParcel = getParcel(start_x + x, start_y + y);
263 if (tempParcel == null) return false; //No such parcel at that point
264 if (tempParcel != startParcel) return false; //Subdividing over 2 parcels; no-no
265 }
266 }
267 }
268 catch (Exception)
269 {
270 return false; //Exception. For now, lets skip subdivision
271 }
272
273 //If we are still here, then they are subdividing within one parcel
274 //Check owner
275 if (startParcel.parcelData.ownerID != attempting_user_id)
276 {
277 return false; //They cant do this!
278 }
279
280 //Lets create a new parcel with bitmap activated at that point (keeping the old parcels info)
281 Parcel newParcel = startParcel.Copy();
282 newParcel.parcelData.parcelName = "Subdivision of " + newParcel.parcelData.parcelName;
283 newParcel.parcelData.globalID = LLUUID.Random();
284
285 newParcel.setParcelBitmap(Parcel.getSquareParcelBitmap(start_x, start_y, end_x, end_y));
286
287 //Now, lets set the subdivision area of the original to false
288 int startParcelIndex = startParcel.parcelData.localID;
289 parcelList[startParcelIndex].setParcelBitmap(Parcel.modifyParcelBitmapSquare(startParcel.getParcelBitmap(), start_x, start_y, end_x, end_y, false));
290 parcelList[startParcelIndex].forceUpdateParcelInfo();
291
292
293 this.setPrimsTainted();
294
295 //Now add the new parcel
296 Parcel result = addParcel(newParcel);
297 result.sendParcelUpdateToAvatarsOverMe();
298
299
300
301
302 return true;
303 }
304 /// <summary>
305 /// Join 2 parcels together
306 /// </summary>
307 /// <param name="start_x">x value in first parcel</param>
308 /// <param name="start_y">y value in first parcel</param>
309 /// <param name="end_x">x value in second parcel</param>
310 /// <param name="end_y">y value in second parcel</param>
311 /// <param name="attempting_user_id">LLUUID of the avatar trying to join the parcels</param>
312 /// <returns>Returns true if successful</returns>
313 private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
314 {
315 end_x -= 4;
316 end_y -= 4;
317
318 List<Parcel> selectedParcels = new List<Parcel>();
319 int stepXSelected = 0;
320 int stepYSelected = 0;
321 for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4)
322 {
323 for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4)
324 {
325 Parcel p = getParcel(stepXSelected,stepYSelected);
326 if (!selectedParcels.Contains(p))
327 {
328 selectedParcels.Add(p);
329 }
330 }
331 }
332 Parcel masterParcel = selectedParcels[0];
333 selectedParcels.RemoveAt(0);
334
335
336 if (selectedParcels.Count < 1)
337 {
338 return false; //Only one parcel selected
339 }
340 if (masterParcel.parcelData.ownerID != attempting_user_id)
341 {
342 return false; //Not the same owner
343 }
344 foreach (Parcel p in selectedParcels)
345 {
346 if (p.parcelData.ownerID != masterParcel.parcelData.ownerID)
347 {
348 return false; //Over multiple users. TODO: make this just ignore this parcel?
349 }
350 }
351 foreach (Parcel slaveParcel in selectedParcels)
352 {
353 parcelList[masterParcel.parcelData.localID].setParcelBitmap(Parcel.mergeParcelBitmaps(masterParcel.getParcelBitmap(), slaveParcel.getParcelBitmap()));
354 performFinalParcelJoin(masterParcel, slaveParcel);
355 }
356
357
358 this.setPrimsTainted();
359
360 masterParcel.sendParcelUpdateToAvatarsOverMe();
361
362 return true;
363
364
365
366 }
367 #endregion
368
369 #region Parcel Updating
370 /// <summary>
371 /// Where we send the ParcelOverlay packet to the client
372 /// </summary>
373 /// <param name="remote_client">The object representing the client</param>
374 public void sendParcelOverlay(IClientAPI remote_client)
375 {
376 const int PARCEL_BLOCKS_PER_PACKET = 1024;
377 int x, y = 0;
378 byte[] byteArray = new byte[PARCEL_BLOCKS_PER_PACKET];
379 int byteArrayCount = 0;
380 int sequenceID = 0;
381 ParcelOverlayPacket packet;
382
383 for (y = 0; y < 64; y++)
384 {
385 for (x = 0; x < 64; x++)
386 {
387 byte tempByte = (byte)0; //This represents the byte for the current 4x4
388 Parcel currentParcelBlock = getParcel(x * 4, y * 4);
389
390 if (currentParcelBlock.parcelData.ownerID == remote_client.AgentId)
391 {
392 //Owner Flag
393 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_OWNED_BY_REQUESTER);
394 }
395 else if (currentParcelBlock.parcelData.salePrice > 0 && (currentParcelBlock.parcelData.authBuyerID == LLUUID.Zero || currentParcelBlock.parcelData.authBuyerID == remote_client.AgentId))
396 {
397 //Sale Flag
398 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_IS_FOR_SALE);
399 }
400 else if (currentParcelBlock.parcelData.ownerID == LLUUID.Zero)
401 {
402 //Public Flag
403 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_PUBLIC);
404 }
405 else
406 {
407 //Other Flag
408 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_OWNED_BY_OTHER);
409 }
410
411
412 //Now for border control
413 if (x == 0)
414 {
415 tempByte = Convert.ToByte(tempByte | PARCEL_FLAG_PROPERTY_BORDER_WEST);
416 }
417 else if (getParcel((x - 1) * 4, y * 4) != currentParcelBlock)
418 {
419 tempByte = Convert.ToByte(tempByte | PARCEL_FLAG_PROPERTY_BORDER_WEST);
420 }
421
422 if (y == 0)
423 {
424 tempByte = Convert.ToByte(tempByte | PARCEL_FLAG_PROPERTY_BORDER_SOUTH);
425 }
426 else if (getParcel(x * 4, (y - 1) * 4) != currentParcelBlock)
427 {
428 tempByte = Convert.ToByte(tempByte | PARCEL_FLAG_PROPERTY_BORDER_SOUTH);
429 }
430
431 byteArray[byteArrayCount] = tempByte;
432 byteArrayCount++;
433 if (byteArrayCount >= PARCEL_BLOCKS_PER_PACKET)
434 {
435 byteArrayCount = 0;
436 packet = new ParcelOverlayPacket();
437 packet.ParcelData.Data = byteArray;
438 packet.ParcelData.SequenceID = sequenceID;
439 remote_client.OutPacket((Packet)packet);
440 sequenceID++;
441 byteArray = new byte[PARCEL_BLOCKS_PER_PACKET];
442 }
443 }
444 }
445
446
447 }
448
449 public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, IClientAPI remote_client)
450 {
451 //Get the parcels within the bounds
452 List<Parcel> temp = new List<Parcel>();
453 int x, y, i;
454 int inc_x = end_x - start_x;
455 int inc_y = end_y - start_y;
456 for (x = 0; x < inc_x; x++)
457 {
458 for (y = 0; y < inc_y; y++)
459 {
460 Parcel currentParcel = getParcel(start_x + x, start_y + y);
461 if (!temp.Contains(currentParcel))
462 {
463 currentParcel.forceUpdateParcelInfo();
464 temp.Add(currentParcel);
465 }
466 }
467 }
468
469 int requestResult = PARCEL_RESULT_ONE_PARCEL;
470 if (temp.Count > 1)
471 {
472 requestResult = PARCEL_RESULT_MULTIPLE_PARCELS;
473 }
474
475 for (i = 0; i < temp.Count; i++)
476 {
477 temp[i].sendParcelProperties(sequence_id, snap_selection, requestResult, remote_client);
478 }
479
480
481 sendParcelOverlay(remote_client);
482 }
483
484 public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
485 {
486 if (parcelList.ContainsKey(packet.ParcelData.LocalID))
487 {
488 parcelList[packet.ParcelData.LocalID].updateParcelProperties(packet, remote_client);
489 }
490 }
491 public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
492 {
493 subdivide(west, south, east, north, remote_client.AgentId);
494 }
495 public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client)
496 {
497 join(west, south, east, north, remote_client.AgentId);
498
499 }
500
501 public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client)
502 {
503 parcelList[local_id].sendForceObjectSelect(local_id, request_type, remote_client);
504 }
505
506 public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client)
507 {
508 parcelList[local_id].sendParcelObjectOwners(remote_client);
509 }
510 #endregion
511
512 /// <summary>
513 /// Resets the sim to the default parcel (full sim parcel owned by the default user)
514 /// </summary>
515 public void resetSimParcels()
516 {
517 //Remove all the parcels in the sim and add a blank, full sim parcel set to public
518 parcelList.Clear();
519 lastParcelLocalID = START_PARCEL_LOCAL_ID - 1;
520 parcelIDList.Initialize();
521
522 Parcel fullSimParcel = new Parcel(LLUUID.Zero, false, m_world);
523
524 fullSimParcel.setParcelBitmap(Parcel.getSquareParcelBitmap(0, 0, 256, 256));
525 fullSimParcel.parcelData.ownerID = m_regInfo.MasterAvatarAssignedUUID;
526
527 addParcel(fullSimParcel);
528
529 }
530
531
532 public void handleSignificantClientMovement(IClientAPI remote_client)
533 {
534 Avatar clientAvatar = m_world.RequestAvatar(remote_client.AgentId);
535 if (clientAvatar != null)
536 {
537 Parcel over = getParcel(clientAvatar.Pos.X,clientAvatar.Pos.Y);
538 if (over != null)
539 {
540 over.sendParcelProperties(0, false, 0, remote_client);
541 }
542 }
543 }
544
545 public void resetAllParcelPrimCounts()
546 {
547 foreach (Parcel p in parcelList.Values)
548 {
549 p.resetParcelPrimCounts();
550 }
551 }
552 public void setPrimsTainted()
553 {
554 this.parcelPrimCountTainted = true;
555 }
556
557 public void addPrimToParcelCounts(SceneObject obj)
558 {
559 LLVector3 position = obj.Pos;
560 Parcel parcelUnderPrim = getParcel(position.X, position.Y);
561 if (parcelUnderPrim != null)
562 {
563 parcelUnderPrim.addPrimToCount(obj);
564 }
565 }
566
567 public void removePrimFromParcelCounts(SceneObject obj)
568 {
569 foreach (Parcel p in parcelList.Values)
570 {
571 p.removePrimFromCount(obj);
572 }
573 }
574
575 public void finalizeParcelPrimCountUpdate()
576 {
577 //Get Simwide prim count for owner
578 Dictionary<LLUUID, List<Parcel>> parcelOwnersAndParcels = new Dictionary<LLUUID,List<Parcel>>();
579 foreach (Parcel p in parcelList.Values)
580 {
581 if(!parcelOwnersAndParcels.ContainsKey(p.parcelData.ownerID))
582 {
583 List<Parcel> tempList = new List<Parcel>();
584 tempList.Add(p);
585 parcelOwnersAndParcels.Add(p.parcelData.ownerID,tempList);
586 }
587 else
588 {
589 parcelOwnersAndParcels[p.parcelData.ownerID].Add(p);
590 }
591 }
592
593 foreach (LLUUID owner in parcelOwnersAndParcels.Keys)
594 {
595 int simArea = 0;
596 int simPrims = 0;
597 foreach (Parcel p in parcelOwnersAndParcels[owner])
598 {
599 simArea += p.parcelData.area;
600 simPrims += p.parcelData.ownerPrims + p.parcelData.otherPrims + p.parcelData.groupPrims + p.parcelData.selectedPrims;
601 }
602
603 foreach (Parcel p in parcelOwnersAndParcels[owner])
604 {
605 p.parcelData.simwideArea = simArea;
606 p.parcelData.simwidePrims = simPrims;
607 }
608 }
609
610 }
611 #endregion
612 }
613 #endregion
614
615
616 #region Parcel Class
617 /// <summary>
618 /// Keeps track of a specific parcel's information
619 /// </summary>
620 public class Parcel
621 {
622 #region Member Variables
623 public ParcelData parcelData = new ParcelData();
624 public List<SceneObject> primsOverMe = new List<SceneObject>();
625
626 public Scene m_world;
627
628 private bool[,] parcelBitmap = new bool[64, 64];
629
630 #endregion
631
632
633 #region Constructors
634 public Parcel(LLUUID owner_id, bool is_group_owned, Scene world)
635 {
636 m_world = world;
637 parcelData.ownerID = owner_id;
638 parcelData.isGroupOwned = is_group_owned;
639
640 }
641 #endregion
642
643
644 #region Member Functions
645
646 #region General Functions
647 /// <summary>
648 /// Checks to see if this parcel contains a point
649 /// </summary>
650 /// <param name="x"></param>
651 /// <param name="y"></param>
652 /// <returns>Returns true if the parcel contains the specified point</returns>
653 public bool containsPoint(int x, int y)
654 {
655 if (x >= 0 && y >= 0 && x <= 256 && x <= 256)
656 {
657 return (parcelBitmap[x / 4, y / 4] == true);
658 }
659 else
660 {
661 return false;
662 }
663 }
664
665 public Parcel Copy()
666 {
667 Parcel newParcel = new Parcel(this.parcelData.ownerID, this.parcelData.isGroupOwned, m_world);
668
669 //Place all new variables here!
670 newParcel.parcelBitmap = (bool[,])(this.parcelBitmap.Clone());
671 newParcel.parcelData = parcelData.Copy();
672
673 return newParcel;
674 }
675
676 #endregion
677
678
679 #region Packet Request Handling
680 /// <summary>
681 /// Sends parcel properties as requested
682 /// </summary>
683 /// <param name="sequence_id">ID sent by client for them to keep track of</param>
684 /// <param name="snap_selection">Bool sent by client for them to use</param>
685 /// <param name="remote_client">Object representing the client</param>
686 public void sendParcelProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
687 {
688
689 ParcelPropertiesPacket updatePacket = new ParcelPropertiesPacket();
690 updatePacket.ParcelData.AABBMax = parcelData.AABBMax;
691 updatePacket.ParcelData.AABBMin = parcelData.AABBMin;
692 updatePacket.ParcelData.Area = parcelData.area;
693 updatePacket.ParcelData.AuctionID = parcelData.auctionID;
694 updatePacket.ParcelData.AuthBuyerID = parcelData.authBuyerID; //unemplemented
695
696 updatePacket.ParcelData.Bitmap = parcelData.parcelBitmapByteArray;
697
698 updatePacket.ParcelData.Desc = Helpers.StringToField(parcelData.parcelDesc);
699 updatePacket.ParcelData.Category = (byte)parcelData.category;
700 updatePacket.ParcelData.ClaimDate = parcelData.claimDate;
701 updatePacket.ParcelData.ClaimPrice = parcelData.claimPrice;
702 updatePacket.ParcelData.GroupID = parcelData.groupID;
703 updatePacket.ParcelData.GroupPrims = parcelData.groupPrims;
704 updatePacket.ParcelData.IsGroupOwned = parcelData.isGroupOwned;
705 updatePacket.ParcelData.LandingType = (byte)parcelData.landingType;
706 updatePacket.ParcelData.LocalID = parcelData.localID;
707 if (parcelData.area > 0)
708 {
709 updatePacket.ParcelData.MaxPrims = Convert.ToInt32(Math.Round((Convert.ToDecimal(parcelData.area) / Convert.ToDecimal(65536)) * 15000 * Convert.ToDecimal(m_world.RegionInfo.estateSettings.objectBonusFactor)));
710 }
711 else
712 {
713 updatePacket.ParcelData.MaxPrims = 0;
714 }
715 updatePacket.ParcelData.MediaAutoScale = parcelData.mediaAutoScale;
716 updatePacket.ParcelData.MediaID = parcelData.mediaID;
717 updatePacket.ParcelData.MediaURL = Helpers.StringToField(parcelData.mediaURL);
718 updatePacket.ParcelData.MusicURL = Helpers.StringToField(parcelData.musicURL);
719 updatePacket.ParcelData.Name = Helpers.StringToField(parcelData.parcelName);
720 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented
721 updatePacket.ParcelData.OtherCount = 0; //unemplemented
722 updatePacket.ParcelData.OtherPrims = parcelData.otherPrims;
723 updatePacket.ParcelData.OwnerID = parcelData.ownerID;
724 updatePacket.ParcelData.OwnerPrims = parcelData.ownerPrims;
725 updatePacket.ParcelData.ParcelFlags = parcelData.parcelFlags;
726 updatePacket.ParcelData.ParcelPrimBonus = m_world.RegionInfo.estateSettings.objectBonusFactor;
727 updatePacket.ParcelData.PassHours = parcelData.passHours;
728 updatePacket.ParcelData.PassPrice = parcelData.passPrice;
729 updatePacket.ParcelData.PublicCount = 0; //unemplemented
730 updatePacket.ParcelData.RegionDenyAnonymous = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.DenyAnonymous) > 0);
731 updatePacket.ParcelData.RegionDenyIdentified = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.DenyIdentified) > 0);
732 updatePacket.ParcelData.RegionDenyTransacted = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.DenyTransacted) > 0);
733 updatePacket.ParcelData.RegionPushOverride = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.RestrictPushObject) > 0);
734 updatePacket.ParcelData.RentPrice = 0;
735 updatePacket.ParcelData.RequestResult = request_result;
736 updatePacket.ParcelData.SalePrice = parcelData.salePrice;
737 updatePacket.ParcelData.SelectedPrims = parcelData.selectedPrims;
738 updatePacket.ParcelData.SelfCount = 0;//unemplemented
739 updatePacket.ParcelData.SequenceID = sequence_id;
740 if (parcelData.simwideArea > 0)
741 {
742 updatePacket.ParcelData.SimWideMaxPrims = Convert.ToInt32(Math.Round((Convert.ToDecimal(parcelData.simwideArea) / Convert.ToDecimal(65536)) * 15000 * Convert.ToDecimal(m_world.RegionInfo.estateSettings.objectBonusFactor)));
743 }
744 else
745 {
746 updatePacket.ParcelData.SimWideMaxPrims = 0;
747 }
748 updatePacket.ParcelData.SimWideTotalPrims = parcelData.simwidePrims;
749 updatePacket.ParcelData.SnapSelection = snap_selection;
750 updatePacket.ParcelData.SnapshotID = parcelData.snapshotID;
751 updatePacket.ParcelData.Status = (byte)parcelData.parcelStatus;
752 updatePacket.ParcelData.TotalPrims = parcelData.ownerPrims + parcelData.groupPrims + parcelData.otherPrims + parcelData.selectedPrims;
753 updatePacket.ParcelData.UserLocation = parcelData.userLocation;
754 updatePacket.ParcelData.UserLookAt = parcelData.userLookAt;
755 remote_client.OutPacket((Packet)updatePacket);
756 }
757
758 public void updateParcelProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
759 {
760 if (remote_client.AgentId == parcelData.ownerID)
761 {
762 //Needs later group support
763 parcelData.authBuyerID = packet.ParcelData.AuthBuyerID;
764 parcelData.category = (libsecondlife.Parcel.ParcelCategory)packet.ParcelData.Category;
765 parcelData.parcelDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc);
766 parcelData.groupID = packet.ParcelData.GroupID;
767 parcelData.landingType = packet.ParcelData.LandingType;
768 parcelData.mediaAutoScale = packet.ParcelData.MediaAutoScale;
769 parcelData.mediaID = packet.ParcelData.MediaID;
770 parcelData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL);
771 parcelData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL);
772 parcelData.parcelName = Helpers.FieldToUTF8String(packet.ParcelData.Name);
773 parcelData.parcelFlags = packet.ParcelData.ParcelFlags;
774 parcelData.passHours = packet.ParcelData.PassHours;
775 parcelData.passPrice = packet.ParcelData.PassPrice;
776 parcelData.salePrice = packet.ParcelData.SalePrice;
777 parcelData.snapshotID = packet.ParcelData.SnapshotID;
778 parcelData.userLocation = packet.ParcelData.UserLocation;
779 parcelData.userLookAt = packet.ParcelData.UserLookAt;
780 sendParcelUpdateToAvatarsOverMe();
781
782
783 }
784 }
785
786 public void sendParcelUpdateToAvatarsOverMe()
787 {
788 List<Avatar> avatars = m_world.RequestAvatarList();
789 for (int i = 0; i < avatars.Count; i++)
790 {
791 Parcel over = m_world.ParcelManager.getParcel((int)Math.Round(avatars[i].Pos.X), (int)Math.Round(avatars[i].Pos.Y));
792 if (over.parcelData.localID == this.parcelData.localID)
793 {
794 sendParcelProperties(0, false, 0, avatars[i].ControllingClient);
795 }
796 }
797 }
798 #endregion
799
800
801 #region Update Functions
802 /// <summary>
803 /// Updates the AABBMin and AABBMax values after area/shape modification of parcel
804 /// </summary>
805 private void updateAABBAndAreaValues()
806 {
807 int min_x = 64;
808 int min_y = 64;
809 int max_x = 0;
810 int max_y = 0;
811 int tempArea = 0;
812 int x, y;
813 for (x = 0; x < 64; x++)
814 {
815 for (y = 0; y < 64; y++)
816 {
817 if (parcelBitmap[x, y] == true)
818 {
819 if (min_x > x) min_x = x;
820 if (min_y > y) min_y = y;
821 if (max_x < x) max_x = x;
822 if (max_y < y) max_y = y;
823 tempArea += 16; //16sqm parcel
824 }
825 }
826 }
827 parcelData.AABBMin = new LLVector3((float)(min_x * 4), (float)(min_y * 4), (float)m_world.Terrain.get((min_x * 4), (min_y * 4)));
828 parcelData.AABBMax = new LLVector3((float)(max_x * 4), (float)(max_y * 4), (float)m_world.Terrain.get((max_x * 4), (max_y * 4)));
829 parcelData.area = tempArea;
830 }
831
832 public void updateParcelBitmapByteArray()
833 {
834 parcelData.parcelBitmapByteArray = convertParcelBitmapToBytes();
835 }
836
837 /// <summary>
838 /// Update all settings in parcel such as area, bitmap byte array, etc
839 /// </summary>
840 public void forceUpdateParcelInfo()
841 {
842 this.updateAABBAndAreaValues();
843 this.updateParcelBitmapByteArray();
844 }
845
846 public void setParcelBitmapFromByteArray()
847 {
848 parcelBitmap = convertBytesToParcelBitmap();
849 }
850 #endregion
851
852
853 #region Parcel Bitmap Functions
854 /// <summary>
855 /// Sets the parcel's bitmap manually
856 /// </summary>
857 /// <param name="bitmap">64x64 block representing where this parcel is on a map</param>
858 public void setParcelBitmap(bool[,] bitmap)
859 {
860 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
861 {
862 //Throw an exception - The bitmap is not 64x64
863 throw new Exception("Error: Invalid Parcel Bitmap");
864 }
865 else
866 {
867 //Valid: Lets set it
868 parcelBitmap = bitmap;
869 forceUpdateParcelInfo();
870
871 }
872 }
873 /// <summary>
874 /// Gets the parcels bitmap manually
875 /// </summary>
876 /// <returns></returns>
877 public bool[,] getParcelBitmap()
878 {
879 return parcelBitmap;
880 }
881 /// <summary>
882 /// Converts the parcel bitmap to a packet friendly byte array
883 /// </summary>
884 /// <returns></returns>
885 private byte[] convertParcelBitmapToBytes()
886 {
887 byte[] tempConvertArr = new byte[512];
888 byte tempByte = 0;
889 int x, y, i, byteNum = 0;
890 i = 0;
891 for (y = 0; y < 64; y++)
892 {
893 for (x = 0; x < 64; x++)
894 {
895 tempByte = Convert.ToByte(tempByte | Convert.ToByte(parcelBitmap[x, y]) << (i++ % 8));
896 if (i % 8 == 0)
897 {
898 tempConvertArr[byteNum] = tempByte;
899 tempByte = (byte)0;
900 i = 0;
901 byteNum++;
902 }
903 }
904 }
905 return tempConvertArr;
906 }
907
908 private bool[,] convertBytesToParcelBitmap()
909 {
910 bool[,] tempConvertMap = new bool[64, 64];
911 tempConvertMap.Initialize();
912 byte tempByte = 0;
913 int x = 0, y = 0, i = 0, bitNum = 0;
914 for (i = 0; i < 512; i++)
915 {
916 tempByte = parcelData.parcelBitmapByteArray[i];
917 for (bitNum = 0; bitNum < 8; bitNum++)
918 {
919 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte)1);
920 tempConvertMap[x, y] = bit;
921 x++;
922 if (x > 63)
923 {
924 x = 0;
925 y++;
926 }
927
928 }
929
930 }
931 return tempConvertMap;
932 }
933 /// <summary>
934 /// Full sim parcel creation
935 /// </summary>
936 /// <returns></returns>
937 public static bool[,] basicFullRegionParcelBitmap()
938 {
939 return getSquareParcelBitmap(0, 0, 256, 256);
940 }
941
942 /// <summary>
943 /// Used to modify the bitmap between the x and y points. Points use 64 scale
944 /// </summary>
945 /// <param name="start_x"></param>
946 /// <param name="start_y"></param>
947 /// <param name="end_x"></param>
948 /// <param name="end_y"></param>
949 /// <returns></returns>
950 public static bool[,] getSquareParcelBitmap(int start_x, int start_y, int end_x, int end_y)
951 {
952
953 bool[,] tempBitmap = new bool[64, 64];
954 tempBitmap.Initialize();
955
956 tempBitmap = modifyParcelBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
957 return tempBitmap;
958 }
959
960 /// <summary>
961 /// Change a parcel's bitmap at within a square and set those points to a specific value
962 /// </summary>
963 /// <param name="parcel_bitmap"></param>
964 /// <param name="start_x"></param>
965 /// <param name="start_y"></param>
966 /// <param name="end_x"></param>
967 /// <param name="end_y"></param>
968 /// <param name="set_value"></param>
969 /// <returns></returns>
970 public static bool[,] modifyParcelBitmapSquare(bool[,] parcel_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value)
971 {
972 if (parcel_bitmap.GetLength(0) != 64 || parcel_bitmap.GetLength(1) != 64 || parcel_bitmap.Rank != 2)
973 {
974 //Throw an exception - The bitmap is not 64x64
975 throw new Exception("Error: Invalid Parcel Bitmap in modifyParcelBitmapSquare()");
976 }
977
978 int x, y;
979 for (y = 0; y < 64; y++)
980 {
981 for (x = 0; x < 64; x++)
982 {
983 if (x >= start_x / 4 && x < end_x / 4
984 && y >= start_y / 4 && y < end_y / 4)
985 {
986 parcel_bitmap[x, y] = set_value;
987 }
988 }
989 }
990 return parcel_bitmap;
991 }
992 /// <summary>
993 /// Join the true values of 2 bitmaps together
994 /// </summary>
995 /// <param name="bitmap_base"></param>
996 /// <param name="bitmap_add"></param>
997 /// <returns></returns>
998 public static bool[,] mergeParcelBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
999 {
1000 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
1001 {
1002 //Throw an exception - The bitmap is not 64x64
1003 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeParcelBitmaps");
1004 }
1005 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
1006 {
1007 //Throw an exception - The bitmap is not 64x64
1008 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeParcelBitmaps");
1009
1010 }
1011
1012 int x, y;
1013 for (y = 0; y < 64; y++)
1014 {
1015 for (x = 0; x < 64; x++)
1016 {
1017 if (bitmap_add[x, y])
1018 {
1019 bitmap_base[x, y] = true;
1020 }
1021 }
1022 }
1023 return bitmap_base;
1024 }
1025 #endregion
1026
1027 #region Object Select and Object Owner Listing
1028 public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client)
1029 {
1030 List<uint> resultLocalIDs = new List<uint>();
1031 foreach (SceneObject obj in primsOverMe)
1032 {
1033 if (obj.rootLocalID > 0)
1034 {
1035 if (request_type == ParcelManager.PARCEL_SELECT_OBJECTS_OWNER && obj.rootPrimitive.OwnerID == this.parcelData.ownerID)
1036 {
1037 resultLocalIDs.Add(obj.rootLocalID);
1038 }
1039 else if (request_type == ParcelManager.PARCEL_SELECT_OBJECTS_GROUP && false) //TODO: change false to group support!
1040 {
1041
1042 }
1043 else if (request_type == ParcelManager.PARCEL_SELECT_OBJECTS_OTHER && obj.rootPrimitive.OwnerID != remote_client.AgentId)
1044 {
1045 resultLocalIDs.Add(obj.rootLocalID);
1046 }
1047 }
1048 }
1049
1050
1051 bool firstCall = true;
1052 int MAX_OBJECTS_PER_PACKET = 251;
1053 ForceObjectSelectPacket pack = new ForceObjectSelectPacket();
1054 ForceObjectSelectPacket.DataBlock[] data;
1055 while (resultLocalIDs.Count > 0)
1056 {
1057 if (firstCall)
1058 {
1059 pack._Header.ResetList = true;
1060 firstCall = false;
1061 }
1062 else
1063 {
1064 pack._Header.ResetList = false;
1065 }
1066
1067 if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET)
1068 {
1069 data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET];
1070 }
1071 else
1072 {
1073 data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count];
1074 }
1075
1076 int i;
1077 for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++)
1078 {
1079 data[i] = new ForceObjectSelectPacket.DataBlock();
1080 data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]);
1081 resultLocalIDs.RemoveAt(0);
1082 }
1083 pack.Data = data;
1084 remote_client.OutPacket((Packet)pack);
1085 }
1086
1087 }
1088 public void sendParcelObjectOwners(IClientAPI remote_client)
1089 {
1090 Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID,int>();
1091 foreach(SceneObject obj in primsOverMe)
1092 {
1093 if(!ownersAndCount.ContainsKey(obj.rootPrimitive.OwnerID))
1094 {
1095 ownersAndCount.Add(obj.rootPrimitive.OwnerID,0);
1096 }
1097 ownersAndCount[obj.rootPrimitive.OwnerID] += obj.primCount;
1098 }
1099 if (ownersAndCount.Count > 0)
1100 {
1101
1102 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[32];
1103
1104 if(ownersAndCount.Count < 32)
1105 {
1106 dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[ownersAndCount.Count];
1107 }
1108
1109
1110 int num = 0;
1111 foreach (LLUUID owner in ownersAndCount.Keys)
1112 {
1113 dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock();
1114 dataBlock[num].Count = ownersAndCount[owner];
1115 dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added
1116 dataBlock[num].OnlineStatus = true; //TODO: fix me later
1117 dataBlock[num].OwnerID = owner;
1118
1119 num++;
1120 }
1121
1122 ParcelObjectOwnersReplyPacket pack = new ParcelObjectOwnersReplyPacket();
1123 pack.Data = dataBlock;
1124 remote_client.OutPacket(pack);
1125 }
1126 }
1127 #endregion
1128
1129 #region Object Returning
1130 public void returnObject(SceneObject obj)
1131 {
1132 }
1133 public void returnParcelObjects(int type, LLUUID owner)
1134 {
1135
1136 }
1137 #endregion
1138
1139 #region Object Adding/Removing from Parcel
1140 public void resetParcelPrimCounts()
1141 {
1142 parcelData.groupPrims = 0;
1143 parcelData.ownerPrims = 0;
1144 parcelData.otherPrims = 0;
1145 parcelData.selectedPrims = 0;
1146 primsOverMe.Clear();
1147 }
1148
1149 public void addPrimToCount(SceneObject obj)
1150 {
1151 LLUUID prim_owner = obj.rootPrimitive.OwnerID;
1152 int prim_count = obj.primCount;
1153
1154 if (obj.isSelected)
1155 {
1156 parcelData.selectedPrims += prim_count;
1157 }
1158 else
1159 {
1160 if (prim_owner == parcelData.ownerID)
1161 {
1162 parcelData.ownerPrims += prim_count;
1163 }
1164 else
1165 {
1166 parcelData.otherPrims += prim_count;
1167 }
1168 }
1169
1170 primsOverMe.Add(obj);
1171
1172 }
1173
1174 public void removePrimFromCount(SceneObject obj)
1175 {
1176 if (primsOverMe.Contains(obj))
1177 {
1178 LLUUID prim_owner = obj.rootPrimitive.OwnerID;
1179 int prim_count = obj.primCount;
1180
1181 if (prim_owner == parcelData.ownerID)
1182 {
1183 parcelData.ownerPrims -= prim_count;
1184 }
1185 else if (prim_owner == parcelData.groupID)
1186 {
1187 parcelData.groupPrims -= prim_count;
1188 }
1189 else
1190 {
1191 parcelData.otherPrims -= prim_count;
1192 }
1193
1194 primsOverMe.Remove(obj);
1195 }
1196 }
1197 #endregion
1198
1199 #endregion
1200
1201
1202 }
1203 #endregion
1204
1205
1206}
diff --git a/OpenSim/Region/Environment/Parcels/Parcel.cs b/OpenSim/Region/Environment/Parcels/Parcel.cs
new file mode 100644
index 0000000..99e9591
--- /dev/null
+++ b/OpenSim/Region/Environment/Parcels/Parcel.cs
@@ -0,0 +1,599 @@
1using System;
2using System.Collections.Generic;
3using libsecondlife;
4using libsecondlife.Packets;
5using OpenSim.Framework.Interfaces;
6using OpenSim.Framework.Types;
7using OpenSim.Region.Environment.Scenes;
8
9namespace OpenSim.Region.Environment.Parcels
10{
11 #region Parcel Class
12 /// <summary>
13 /// Keeps track of a specific parcel's information
14 /// </summary>
15 public class Parcel
16 {
17 #region Member Variables
18 public ParcelData parcelData = new ParcelData();
19 public List<SceneObject> primsOverMe = new List<SceneObject>();
20
21 public Scene m_world;
22
23 private bool[,] parcelBitmap = new bool[64, 64];
24
25 #endregion
26
27
28 #region Constructors
29 public Parcel(LLUUID owner_id, bool is_group_owned, Scene world)
30 {
31 m_world = world;
32 parcelData.ownerID = owner_id;
33 parcelData.isGroupOwned = is_group_owned;
34
35 }
36 #endregion
37
38
39 #region Member Functions
40
41 #region General Functions
42 /// <summary>
43 /// Checks to see if this parcel contains a point
44 /// </summary>
45 /// <param name="x"></param>
46 /// <param name="y"></param>
47 /// <returns>Returns true if the parcel contains the specified point</returns>
48 public bool containsPoint(int x, int y)
49 {
50 if (x >= 0 && y >= 0 && x <= 256 && x <= 256)
51 {
52 return (parcelBitmap[x / 4, y / 4] == true);
53 }
54 else
55 {
56 return false;
57 }
58 }
59
60 public Parcel Copy()
61 {
62 Parcel newParcel = new Parcel(this.parcelData.ownerID, this.parcelData.isGroupOwned, m_world);
63
64 //Place all new variables here!
65 newParcel.parcelBitmap = (bool[,])(this.parcelBitmap.Clone());
66 newParcel.parcelData = parcelData.Copy();
67
68 return newParcel;
69 }
70
71 #endregion
72
73
74 #region Packet Request Handling
75 /// <summary>
76 /// Sends parcel properties as requested
77 /// </summary>
78 /// <param name="sequence_id">ID sent by client for them to keep track of</param>
79 /// <param name="snap_selection">Bool sent by client for them to use</param>
80 /// <param name="remote_client">Object representing the client</param>
81 public void sendParcelProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
82 {
83
84 ParcelPropertiesPacket updatePacket = new ParcelPropertiesPacket();
85 updatePacket.ParcelData.AABBMax = parcelData.AABBMax;
86 updatePacket.ParcelData.AABBMin = parcelData.AABBMin;
87 updatePacket.ParcelData.Area = parcelData.area;
88 updatePacket.ParcelData.AuctionID = parcelData.auctionID;
89 updatePacket.ParcelData.AuthBuyerID = parcelData.authBuyerID; //unemplemented
90
91 updatePacket.ParcelData.Bitmap = parcelData.parcelBitmapByteArray;
92
93 updatePacket.ParcelData.Desc = Helpers.StringToField(parcelData.parcelDesc);
94 updatePacket.ParcelData.Category = (byte)parcelData.category;
95 updatePacket.ParcelData.ClaimDate = parcelData.claimDate;
96 updatePacket.ParcelData.ClaimPrice = parcelData.claimPrice;
97 updatePacket.ParcelData.GroupID = parcelData.groupID;
98 updatePacket.ParcelData.GroupPrims = parcelData.groupPrims;
99 updatePacket.ParcelData.IsGroupOwned = parcelData.isGroupOwned;
100 updatePacket.ParcelData.LandingType = (byte)parcelData.landingType;
101 updatePacket.ParcelData.LocalID = parcelData.localID;
102 if (parcelData.area > 0)
103 {
104 updatePacket.ParcelData.MaxPrims = Convert.ToInt32(Math.Round((Convert.ToDecimal(parcelData.area) / Convert.ToDecimal(65536)) * 15000 * Convert.ToDecimal(m_world.RegionInfo.estateSettings.objectBonusFactor)));
105 }
106 else
107 {
108 updatePacket.ParcelData.MaxPrims = 0;
109 }
110 updatePacket.ParcelData.MediaAutoScale = parcelData.mediaAutoScale;
111 updatePacket.ParcelData.MediaID = parcelData.mediaID;
112 updatePacket.ParcelData.MediaURL = Helpers.StringToField(parcelData.mediaURL);
113 updatePacket.ParcelData.MusicURL = Helpers.StringToField(parcelData.musicURL);
114 updatePacket.ParcelData.Name = Helpers.StringToField(parcelData.parcelName);
115 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented
116 updatePacket.ParcelData.OtherCount = 0; //unemplemented
117 updatePacket.ParcelData.OtherPrims = parcelData.otherPrims;
118 updatePacket.ParcelData.OwnerID = parcelData.ownerID;
119 updatePacket.ParcelData.OwnerPrims = parcelData.ownerPrims;
120 updatePacket.ParcelData.ParcelFlags = parcelData.parcelFlags;
121 updatePacket.ParcelData.ParcelPrimBonus = m_world.RegionInfo.estateSettings.objectBonusFactor;
122 updatePacket.ParcelData.PassHours = parcelData.passHours;
123 updatePacket.ParcelData.PassPrice = parcelData.passPrice;
124 updatePacket.ParcelData.PublicCount = 0; //unemplemented
125 updatePacket.ParcelData.RegionDenyAnonymous = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.DenyAnonymous) > 0);
126 updatePacket.ParcelData.RegionDenyIdentified = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.DenyIdentified) > 0);
127 updatePacket.ParcelData.RegionDenyTransacted = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.DenyTransacted) > 0);
128 updatePacket.ParcelData.RegionPushOverride = (((uint)m_world.RegionInfo.estateSettings.regionFlags & (uint)Simulator.RegionFlags.RestrictPushObject) > 0);
129 updatePacket.ParcelData.RentPrice = 0;
130 updatePacket.ParcelData.RequestResult = request_result;
131 updatePacket.ParcelData.SalePrice = parcelData.salePrice;
132 updatePacket.ParcelData.SelectedPrims = parcelData.selectedPrims;
133 updatePacket.ParcelData.SelfCount = 0;//unemplemented
134 updatePacket.ParcelData.SequenceID = sequence_id;
135 if (parcelData.simwideArea > 0)
136 {
137 updatePacket.ParcelData.SimWideMaxPrims = Convert.ToInt32(Math.Round((Convert.ToDecimal(parcelData.simwideArea) / Convert.ToDecimal(65536)) * 15000 * Convert.ToDecimal(m_world.RegionInfo.estateSettings.objectBonusFactor)));
138 }
139 else
140 {
141 updatePacket.ParcelData.SimWideMaxPrims = 0;
142 }
143 updatePacket.ParcelData.SimWideTotalPrims = parcelData.simwidePrims;
144 updatePacket.ParcelData.SnapSelection = snap_selection;
145 updatePacket.ParcelData.SnapshotID = parcelData.snapshotID;
146 updatePacket.ParcelData.Status = (byte)parcelData.parcelStatus;
147 updatePacket.ParcelData.TotalPrims = parcelData.ownerPrims + parcelData.groupPrims + parcelData.otherPrims + parcelData.selectedPrims;
148 updatePacket.ParcelData.UserLocation = parcelData.userLocation;
149 updatePacket.ParcelData.UserLookAt = parcelData.userLookAt;
150 remote_client.OutPacket((Packet)updatePacket);
151 }
152
153 public void updateParcelProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
154 {
155 if (remote_client.AgentId == parcelData.ownerID)
156 {
157 //Needs later group support
158 parcelData.authBuyerID = packet.ParcelData.AuthBuyerID;
159 parcelData.category = (libsecondlife.Parcel.ParcelCategory)packet.ParcelData.Category;
160 parcelData.parcelDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc);
161 parcelData.groupID = packet.ParcelData.GroupID;
162 parcelData.landingType = packet.ParcelData.LandingType;
163 parcelData.mediaAutoScale = packet.ParcelData.MediaAutoScale;
164 parcelData.mediaID = packet.ParcelData.MediaID;
165 parcelData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL);
166 parcelData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL);
167 parcelData.parcelName = Helpers.FieldToUTF8String(packet.ParcelData.Name);
168 parcelData.parcelFlags = packet.ParcelData.ParcelFlags;
169 parcelData.passHours = packet.ParcelData.PassHours;
170 parcelData.passPrice = packet.ParcelData.PassPrice;
171 parcelData.salePrice = packet.ParcelData.SalePrice;
172 parcelData.snapshotID = packet.ParcelData.SnapshotID;
173 parcelData.userLocation = packet.ParcelData.UserLocation;
174 parcelData.userLookAt = packet.ParcelData.UserLookAt;
175 sendParcelUpdateToAvatarsOverMe();
176
177
178 }
179 }
180
181 public void sendParcelUpdateToAvatarsOverMe()
182 {
183 List<ScenePresence> avatars = m_world.RequestAvatarList();
184 for (int i = 0; i < avatars.Count; i++)
185 {
186 Parcel over = m_world.LandManager.getParcel((int)Math.Round(avatars[i].Pos.X), (int)Math.Round(avatars[i].Pos.Y));
187 if (over.parcelData.localID == this.parcelData.localID)
188 {
189 sendParcelProperties(0, false, 0, avatars[i].ControllingClient);
190 }
191 }
192 }
193 #endregion
194
195
196 #region Update Functions
197 /// <summary>
198 /// Updates the AABBMin and AABBMax values after area/shape modification of parcel
199 /// </summary>
200 private void updateAABBAndAreaValues()
201 {
202 int min_x = 64;
203 int min_y = 64;
204 int max_x = 0;
205 int max_y = 0;
206 int tempArea = 0;
207 int x, y;
208 for (x = 0; x < 64; x++)
209 {
210 for (y = 0; y < 64; y++)
211 {
212 if (parcelBitmap[x, y] == true)
213 {
214 if (min_x > x) min_x = x;
215 if (min_y > y) min_y = y;
216 if (max_x < x) max_x = x;
217 if (max_y < y) max_y = y;
218 tempArea += 16; //16sqm parcel
219 }
220 }
221 }
222 parcelData.AABBMin = new LLVector3((float)(min_x * 4), (float)(min_y * 4), (float)m_world.Terrain.get((min_x * 4), (min_y * 4)));
223 parcelData.AABBMax = new LLVector3((float)(max_x * 4), (float)(max_y * 4), (float)m_world.Terrain.get((max_x * 4), (max_y * 4)));
224 parcelData.area = tempArea;
225 }
226
227 public void updateParcelBitmapByteArray()
228 {
229 parcelData.parcelBitmapByteArray = convertParcelBitmapToBytes();
230 }
231
232 /// <summary>
233 /// Update all settings in parcel such as area, bitmap byte array, etc
234 /// </summary>
235 public void forceUpdateParcelInfo()
236 {
237 this.updateAABBAndAreaValues();
238 this.updateParcelBitmapByteArray();
239 }
240
241 public void setParcelBitmapFromByteArray()
242 {
243 parcelBitmap = convertBytesToParcelBitmap();
244 }
245 #endregion
246
247
248 #region Parcel Bitmap Functions
249 /// <summary>
250 /// Sets the parcel's bitmap manually
251 /// </summary>
252 /// <param name="bitmap">64x64 block representing where this parcel is on a map</param>
253 public void setParcelBitmap(bool[,] bitmap)
254 {
255 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
256 {
257 //Throw an exception - The bitmap is not 64x64
258 throw new Exception("Error: Invalid Parcel Bitmap");
259 }
260 else
261 {
262 //Valid: Lets set it
263 parcelBitmap = bitmap;
264 forceUpdateParcelInfo();
265
266 }
267 }
268 /// <summary>
269 /// Gets the parcels bitmap manually
270 /// </summary>
271 /// <returns></returns>
272 public bool[,] getParcelBitmap()
273 {
274 return parcelBitmap;
275 }
276 /// <summary>
277 /// Converts the parcel bitmap to a packet friendly byte array
278 /// </summary>
279 /// <returns></returns>
280 private byte[] convertParcelBitmapToBytes()
281 {
282 byte[] tempConvertArr = new byte[512];
283 byte tempByte = 0;
284 int x, y, i, byteNum = 0;
285 i = 0;
286 for (y = 0; y < 64; y++)
287 {
288 for (x = 0; x < 64; x++)
289 {
290 tempByte = Convert.ToByte(tempByte | Convert.ToByte(parcelBitmap[x, y]) << (i++ % 8));
291 if (i % 8 == 0)
292 {
293 tempConvertArr[byteNum] = tempByte;
294 tempByte = (byte)0;
295 i = 0;
296 byteNum++;
297 }
298 }
299 }
300 return tempConvertArr;
301 }
302
303 private bool[,] convertBytesToParcelBitmap()
304 {
305 bool[,] tempConvertMap = new bool[64, 64];
306 tempConvertMap.Initialize();
307 byte tempByte = 0;
308 int x = 0, y = 0, i = 0, bitNum = 0;
309 for (i = 0; i < 512; i++)
310 {
311 tempByte = parcelData.parcelBitmapByteArray[i];
312 for (bitNum = 0; bitNum < 8; bitNum++)
313 {
314 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte)1);
315 tempConvertMap[x, y] = bit;
316 x++;
317 if (x > 63)
318 {
319 x = 0;
320 y++;
321 }
322
323 }
324
325 }
326 return tempConvertMap;
327 }
328 /// <summary>
329 /// Full sim parcel creation
330 /// </summary>
331 /// <returns></returns>
332 public static bool[,] basicFullRegionParcelBitmap()
333 {
334 return getSquareParcelBitmap(0, 0, 256, 256);
335 }
336
337 /// <summary>
338 /// Used to modify the bitmap between the x and y points. Points use 64 scale
339 /// </summary>
340 /// <param name="start_x"></param>
341 /// <param name="start_y"></param>
342 /// <param name="end_x"></param>
343 /// <param name="end_y"></param>
344 /// <returns></returns>
345 public static bool[,] getSquareParcelBitmap(int start_x, int start_y, int end_x, int end_y)
346 {
347
348 bool[,] tempBitmap = new bool[64, 64];
349 tempBitmap.Initialize();
350
351 tempBitmap = modifyParcelBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
352 return tempBitmap;
353 }
354
355 /// <summary>
356 /// Change a parcel's bitmap at within a square and set those points to a specific value
357 /// </summary>
358 /// <param name="parcel_bitmap"></param>
359 /// <param name="start_x"></param>
360 /// <param name="start_y"></param>
361 /// <param name="end_x"></param>
362 /// <param name="end_y"></param>
363 /// <param name="set_value"></param>
364 /// <returns></returns>
365 public static bool[,] modifyParcelBitmapSquare(bool[,] parcel_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value)
366 {
367 if (parcel_bitmap.GetLength(0) != 64 || parcel_bitmap.GetLength(1) != 64 || parcel_bitmap.Rank != 2)
368 {
369 //Throw an exception - The bitmap is not 64x64
370 throw new Exception("Error: Invalid Parcel Bitmap in modifyParcelBitmapSquare()");
371 }
372
373 int x, y;
374 for (y = 0; y < 64; y++)
375 {
376 for (x = 0; x < 64; x++)
377 {
378 if (x >= start_x / 4 && x < end_x / 4
379 && y >= start_y / 4 && y < end_y / 4)
380 {
381 parcel_bitmap[x, y] = set_value;
382 }
383 }
384 }
385 return parcel_bitmap;
386 }
387 /// <summary>
388 /// Join the true values of 2 bitmaps together
389 /// </summary>
390 /// <param name="bitmap_base"></param>
391 /// <param name="bitmap_add"></param>
392 /// <returns></returns>
393 public static bool[,] mergeParcelBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
394 {
395 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
396 {
397 //Throw an exception - The bitmap is not 64x64
398 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeParcelBitmaps");
399 }
400 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
401 {
402 //Throw an exception - The bitmap is not 64x64
403 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeParcelBitmaps");
404
405 }
406
407 int x, y;
408 for (y = 0; y < 64; y++)
409 {
410 for (x = 0; x < 64; x++)
411 {
412 if (bitmap_add[x, y])
413 {
414 bitmap_base[x, y] = true;
415 }
416 }
417 }
418 return bitmap_base;
419 }
420 #endregion
421
422 #region Object Select and Object Owner Listing
423 public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client)
424 {
425 List<uint> resultLocalIDs = new List<uint>();
426 foreach (SceneObject obj in primsOverMe)
427 {
428 if (obj.rootLocalID > 0)
429 {
430 if (request_type == LandManager.PARCEL_SELECT_OBJECTS_OWNER && obj.rootPrimitive.OwnerID == this.parcelData.ownerID)
431 {
432 resultLocalIDs.Add(obj.rootLocalID);
433 }
434 else if (request_type == LandManager.PARCEL_SELECT_OBJECTS_GROUP && false) //TODO: change false to group support!
435 {
436
437 }
438 else if (request_type == LandManager.PARCEL_SELECT_OBJECTS_OTHER && obj.rootPrimitive.OwnerID != remote_client.AgentId)
439 {
440 resultLocalIDs.Add(obj.rootLocalID);
441 }
442 }
443 }
444
445
446 bool firstCall = true;
447 int MAX_OBJECTS_PER_PACKET = 251;
448 ForceObjectSelectPacket pack = new ForceObjectSelectPacket();
449 ForceObjectSelectPacket.DataBlock[] data;
450 while (resultLocalIDs.Count > 0)
451 {
452 if (firstCall)
453 {
454 pack._Header.ResetList = true;
455 firstCall = false;
456 }
457 else
458 {
459 pack._Header.ResetList = false;
460 }
461
462 if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET)
463 {
464 data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET];
465 }
466 else
467 {
468 data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count];
469 }
470
471 int i;
472 for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++)
473 {
474 data[i] = new ForceObjectSelectPacket.DataBlock();
475 data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]);
476 resultLocalIDs.RemoveAt(0);
477 }
478 pack.Data = data;
479 remote_client.OutPacket((Packet)pack);
480 }
481
482 }
483 public void sendParcelObjectOwners(IClientAPI remote_client)
484 {
485 Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>();
486 foreach (SceneObject obj in primsOverMe)
487 {
488 if (!ownersAndCount.ContainsKey(obj.rootPrimitive.OwnerID))
489 {
490 ownersAndCount.Add(obj.rootPrimitive.OwnerID, 0);
491 }
492 ownersAndCount[obj.rootPrimitive.OwnerID] += obj.primCount;
493 }
494 if (ownersAndCount.Count > 0)
495 {
496
497 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[32];
498
499 if (ownersAndCount.Count < 32)
500 {
501 dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[ownersAndCount.Count];
502 }
503
504
505 int num = 0;
506 foreach (LLUUID owner in ownersAndCount.Keys)
507 {
508 dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock();
509 dataBlock[num].Count = ownersAndCount[owner];
510 dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added
511 dataBlock[num].OnlineStatus = true; //TODO: fix me later
512 dataBlock[num].OwnerID = owner;
513
514 num++;
515 }
516
517 ParcelObjectOwnersReplyPacket pack = new ParcelObjectOwnersReplyPacket();
518 pack.Data = dataBlock;
519 remote_client.OutPacket(pack);
520 }
521 }
522 #endregion
523
524 #region Object Returning
525 public void returnObject(SceneObject obj)
526 {
527 }
528 public void returnParcelObjects(int type, LLUUID owner)
529 {
530
531 }
532 #endregion
533
534 #region Object Adding/Removing from Parcel
535 public void resetParcelPrimCounts()
536 {
537 parcelData.groupPrims = 0;
538 parcelData.ownerPrims = 0;
539 parcelData.otherPrims = 0;
540 parcelData.selectedPrims = 0;
541 primsOverMe.Clear();
542 }
543
544 public void addPrimToCount(SceneObject obj)
545 {
546 LLUUID prim_owner = obj.rootPrimitive.OwnerID;
547 int prim_count = obj.primCount;
548
549 if (obj.isSelected)
550 {
551 parcelData.selectedPrims += prim_count;
552 }
553 else
554 {
555 if (prim_owner == parcelData.ownerID)
556 {
557 parcelData.ownerPrims += prim_count;
558 }
559 else
560 {
561 parcelData.otherPrims += prim_count;
562 }
563 }
564
565 primsOverMe.Add(obj);
566
567 }
568
569 public void removePrimFromCount(SceneObject obj)
570 {
571 if (primsOverMe.Contains(obj))
572 {
573 LLUUID prim_owner = obj.rootPrimitive.OwnerID;
574 int prim_count = obj.primCount;
575
576 if (prim_owner == parcelData.ownerID)
577 {
578 parcelData.ownerPrims -= prim_count;
579 }
580 else if (prim_owner == parcelData.groupID)
581 {
582 parcelData.groupPrims -= prim_count;
583 }
584 else
585 {
586 parcelData.otherPrims -= prim_count;
587 }
588
589 primsOverMe.Remove(obj);
590 }
591 }
592 #endregion
593
594 #endregion
595
596
597 }
598 #endregion
599}
diff --git a/OpenSim/Region/Environment/RegionManager.cs b/OpenSim/Region/Environment/RegionManager.cs
index 35fbf45..eb30389 100644
--- a/OpenSim/Region/Environment/RegionManager.cs
+++ b/OpenSim/Region/Environment/RegionManager.cs
@@ -4,6 +4,7 @@ using OpenSim.Framework.Communications;
4using OpenSim.Framework.Servers; 4using OpenSim.Framework.Servers;
5using OpenSim.Region.Capabilities; 5using OpenSim.Region.Capabilities;
6using OpenSim.Region.Environment.Scenes; 6using OpenSim.Region.Environment.Scenes;
7using OpenSim.Region.Environment.Parcels;
7 8
8namespace OpenSim.Region.Environment 9namespace OpenSim.Region.Environment
9{ 10{
@@ -17,7 +18,7 @@ namespace OpenSim.Region.Environment
17 18
18 protected Scene m_Scene; 19 protected Scene m_Scene;
19 20
20 public ParcelManager parcelManager; 21 public LandManager LandManager;
21 public EstateManager estateManager; 22 public EstateManager estateManager;
22 23
23 public RegionManager() 24 public RegionManager()
diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs
index e37d105..18c9637 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs
@@ -342,7 +342,7 @@ namespace OpenSim.Region.Environment.Scenes
342 { 342 {
343 ((SceneObject)ent).GetProperites(remoteClient); 343 ((SceneObject)ent).GetProperites(remoteClient);
344 ((SceneObject)ent).isSelected = true; 344 ((SceneObject)ent).isSelected = true;
345 this.ParcelManager.setPrimsTainted(); 345 this.LandManager.setPrimsTainted();
346 break; 346 break;
347 } 347 }
348 } 348 }
@@ -363,7 +363,7 @@ namespace OpenSim.Region.Environment.Scenes
363 if (((SceneObject)ent).rootLocalID == primLocalID) 363 if (((SceneObject)ent).rootLocalID == primLocalID)
364 { 364 {
365 ((SceneObject)ent).isSelected = false; 365 ((SceneObject)ent).isSelected = false;
366 this.ParcelManager.setPrimsTainted(); 366 this.LandManager.setPrimsTainted();
367 break; 367 break;
368 } 368 }
369 } 369 }
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index a06d74d..5689308 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -45,6 +45,8 @@ using OpenSim.Region.Terrain;
45using Caps = OpenSim.Region.Capabilities.Caps; 45using Caps = OpenSim.Region.Capabilities.Caps;
46using Timer = System.Timers.Timer; 46using Timer = System.Timers.Timer;
47 47
48using OpenSim.Region.Environment.Parcels;
49
48namespace OpenSim.Region.Environment.Scenes 50namespace OpenSim.Region.Environment.Scenes
49{ 51{
50 public delegate bool FilterAvatarList(ScenePresence avatar); 52 public delegate bool FilterAvatarList(ScenePresence avatar);
@@ -88,10 +90,10 @@ namespace OpenSim.Region.Environment.Scenes
88 } 90 }
89 } 91 }
90 92
91 private ParcelManager m_parcelManager; 93 private LandManager m_LandManager;
92 public ParcelManager ParcelManager 94 public LandManager LandManager
93 { 95 {
94 get { return m_parcelManager; } 96 get { return m_LandManager; }
95 } 97 }
96 98
97 private EstateManager m_estateManager; 99 private EstateManager m_estateManager;
@@ -139,12 +141,12 @@ namespace OpenSim.Region.Environment.Scenes
139 this.m_datastore = m_regInfo.DataStore; 141 this.m_datastore = m_regInfo.DataStore;
140 this.RegisterRegionWithComms(); 142 this.RegisterRegionWithComms();
141 143
142 m_parcelManager = new ParcelManager(this, this.m_regInfo); 144 m_LandManager = new LandManager(this, this.m_regInfo);
143 m_estateManager = new EstateManager(this, this.m_regInfo); 145 m_estateManager = new EstateManager(this, this.m_regInfo);
144 m_scriptManager = new ScriptManager(this); 146 m_scriptManager = new ScriptManager(this);
145 m_eventManager = new EventManager(); 147 m_eventManager = new EventManager();
146 148
147 m_eventManager.OnParcelPrimCountAdd += new EventManager.OnParcelPrimCountAddDelegate(m_parcelManager.addPrimToParcelCounts); 149 m_eventManager.OnParcelPrimCountAdd += new EventManager.OnParcelPrimCountAddDelegate(m_LandManager.addPrimToParcelCounts);
148 150
149 MainLog.Instance.Verbose("World.cs - creating new entitities instance"); 151 MainLog.Instance.Verbose("World.cs - creating new entitities instance");
150 Entities = new Dictionary<LLUUID, EntityBase>(); 152 Entities = new Dictionary<LLUUID, EntityBase>();
@@ -245,7 +247,7 @@ namespace OpenSim.Region.Environment.Scenes
245 this.parcelPrimCheckCount++; 247 this.parcelPrimCheckCount++;
246 if (this.parcelPrimCheckCount > 50) //check every 5 seconds for tainted prims 248 if (this.parcelPrimCheckCount > 50) //check every 5 seconds for tainted prims
247 { 249 {
248 if (m_parcelManager.parcelPrimCountTainted) 250 if (m_LandManager.parcelPrimCountTainted)
249 { 251 {
250 //Perform parcel update of prim count 252 //Perform parcel update of prim count
251 performParcelPrimCountUpdate(); 253 performParcelPrimCountUpdate();
@@ -511,9 +513,9 @@ namespace OpenSim.Region.Environment.Scenes
511 { 513 {
512 if (this.Entities.ContainsKey(sceneObject.rootUUID)) 514 if (this.Entities.ContainsKey(sceneObject.rootUUID))
513 { 515 {
514 m_parcelManager.removePrimFromParcelCounts(sceneObject); 516 m_LandManager.removePrimFromParcelCounts(sceneObject);
515 this.Entities.Remove(sceneObject.rootUUID); 517 this.Entities.Remove(sceneObject.rootUUID);
516 m_parcelManager.setPrimsTainted(); 518 m_LandManager.setPrimsTainted();
517 } 519 }
518 } 520 }
519 521
@@ -523,7 +525,7 @@ namespace OpenSim.Region.Environment.Scenes
523 /// <param name="prim"></param> 525 /// <param name="prim"></param>
524 public void AcknowledgeNewPrim(Primitive prim) 526 public void AcknowledgeNewPrim(Primitive prim)
525 { 527 {
526 prim.OnPrimCountTainted += m_parcelManager.setPrimsTainted; 528 prim.OnPrimCountTainted += m_LandManager.setPrimsTainted;
527 } 529 }
528 #endregion 530 #endregion
529 531
@@ -540,7 +542,7 @@ namespace OpenSim.Region.Environment.Scenes
540 SubscribeToClientEvents(client); 542 SubscribeToClientEvents(client);
541 this.m_estateManager.sendRegionHandshake(client); 543 this.m_estateManager.sendRegionHandshake(client);
542 CreateAndAddScenePresence(client); 544 CreateAndAddScenePresence(client);
543 this.m_parcelManager.sendParcelOverlay(client); 545 this.m_LandManager.sendParcelOverlay(client);
544 546
545 } 547 }
546 548
@@ -571,12 +573,12 @@ namespace OpenSim.Region.Environment.Scenes
571 client.OnLinkObjects += this.LinkObjects; 573 client.OnLinkObjects += this.LinkObjects;
572 client.OnObjectDuplicate += this.DuplicateObject; 574 client.OnObjectDuplicate += this.DuplicateObject;
573 575
574 client.OnParcelPropertiesRequest += new ParcelPropertiesRequest(m_parcelManager.handleParcelPropertiesRequest); 576 client.OnParcelPropertiesRequest += new ParcelPropertiesRequest(m_LandManager.handleParcelPropertiesRequest);
575 client.OnParcelDivideRequest += new ParcelDivideRequest(m_parcelManager.handleParcelDivideRequest); 577 client.OnParcelDivideRequest += new ParcelDivideRequest(m_LandManager.handleParcelDivideRequest);
576 client.OnParcelJoinRequest += new ParcelJoinRequest(m_parcelManager.handleParcelJoinRequest); 578 client.OnParcelJoinRequest += new ParcelJoinRequest(m_LandManager.handleParcelJoinRequest);
577 client.OnParcelPropertiesUpdateRequest += new ParcelPropertiesUpdateRequest(m_parcelManager.handleParcelPropertiesUpdateRequest); 579 client.OnParcelPropertiesUpdateRequest += new ParcelPropertiesUpdateRequest(m_LandManager.handleParcelPropertiesUpdateRequest);
578 client.OnParcelSelectObjects += new ParcelSelectObjects(m_parcelManager.handleParcelSelectObjectsRequest); 580 client.OnParcelSelectObjects += new ParcelSelectObjects(m_LandManager.handleParcelSelectObjectsRequest);
579 client.OnParcelObjectOwnerRequest += new ParcelObjectOwnerRequest(m_parcelManager.handleParcelObjectOwnersRequest); 581 client.OnParcelObjectOwnerRequest += new ParcelObjectOwnerRequest(m_LandManager.handleParcelObjectOwnersRequest);
580 582
581 client.OnEstateOwnerMessage += new EstateOwnerMessageRequest(m_estateManager.handleEstateOwnerMessage); 583 client.OnEstateOwnerMessage += new EstateOwnerMessageRequest(m_estateManager.handleEstateOwnerMessage);
582 584
@@ -619,7 +621,7 @@ namespace OpenSim.Region.Environment.Scenes
619 this.Avatars.Add(client.AgentId, newAvatar); 621 this.Avatars.Add(client.AgentId, newAvatar);
620 } 622 }
621 } 623 }
622 newAvatar.OnSignificantClientMovement += m_parcelManager.handleSignificantClientMovement; 624 newAvatar.OnSignificantClientMovement += m_LandManager.handleSignificantClientMovement;
623 return newAvatar; 625 return newAvatar;
624 } 626 }
625 627
@@ -908,10 +910,10 @@ namespace OpenSim.Region.Environment.Scenes
908 910
909 public void performParcelPrimCountUpdate() 911 public void performParcelPrimCountUpdate()
910 { 912 {
911 m_parcelManager.resetAllParcelPrimCounts(); 913 m_LandManager.resetAllParcelPrimCounts();
912 m_eventManager.TriggerParcelPrimCountUpdate(); 914 m_eventManager.TriggerParcelPrimCountUpdate();
913 m_parcelManager.finalizeParcelPrimCountUpdate(); 915 m_LandManager.finalizeParcelPrimCountUpdate();
914 m_parcelManager.parcelPrimCountTainted = false; 916 m_LandManager.parcelPrimCountTainted = false;
915 } 917 }
916 #endregion 918 #endregion
917 919
diff --git a/OpenSim/Region/Examples/SimpleApp/Program.cs b/OpenSim/Region/Examples/SimpleApp/Program.cs
index 131159e..631e076 100644
--- a/OpenSim/Region/Examples/SimpleApp/Program.cs
+++ b/OpenSim/Region/Examples/SimpleApp/Program.cs
@@ -82,7 +82,7 @@ namespace SimpleApp
82 if (masterAvatar != null) 82 if (masterAvatar != null)
83 { 83 {
84 world.RegionInfo.MasterAvatarAssignedUUID = masterAvatar.UUID; 84 world.RegionInfo.MasterAvatarAssignedUUID = masterAvatar.UUID;
85 world.ParcelManager.NoParcelDataFromStorage(); 85 world.LandManager.NoParcelDataFromStorage();
86 } 86 }
87 87
88 world.StartTimer(); 88 world.StartTimer();
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs
index 3ce0967..9dc20c3 100644
--- a/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs
+++ b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs
@@ -48,14 +48,14 @@ namespace OpenSim.DataStore.NullStorage
48 48
49 } 49 }
50 50
51 public void StoreParcel(OpenSim.Region.Environment.Parcel parcel) 51 public void StoreParcel(OpenSim.Region.Environment.Parcels.Parcel parcel)
52 { 52 {
53 53
54 } 54 }
55 55
56 public List<OpenSim.Region.Environment.Parcel> LoadParcels() 56 public List<OpenSim.Region.Environment.Parcels.Parcel> LoadParcels()
57 { 57 {
58 return new List<OpenSim.Region.Environment.Parcel>(); 58 return new List<OpenSim.Region.Environment.Parcels.Parcel>();
59 } 59 }
60 60
61 public void Shutdown() 61 public void Shutdown()