aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/OpenSim.RegionServer/world
diff options
context:
space:
mode:
authormingchen2007-06-04 14:09:19 +0000
committermingchen2007-06-04 14:09:19 +0000
commit17421593528f4126256dea6d0c844da9c218fdb7 (patch)
tree69025fb439a08c24787a226b708f7b271610c548 /OpenSim/OpenSim.RegionServer/world
parentSmall bugfix. (diff)
downloadopensim-SC-17421593528f4126256dea6d0c844da9c218fdb7.zip
opensim-SC-17421593528f4126256dea6d0c844da9c218fdb7.tar.gz
opensim-SC-17421593528f4126256dea6d0c844da9c218fdb7.tar.bz2
opensim-SC-17421593528f4126256dea6d0c844da9c218fdb7.tar.xz
Parcel Manager Changes:
*Added Parcel Backup Support for DB4. Other storages currently do not save *Added parcelIDList in ParcelManager to speed up parcel fetching at position *Added ParcelData.cs and ParcelData class for better storage support *Documentation for parcel added *2 Parcel Related bug fixes
Diffstat (limited to '')
-rw-r--r--OpenSim/OpenSim.RegionServer/world/ParcelManager.cs499
-rw-r--r--OpenSim/OpenSim.RegionServer/world/World.PacketHandlers.cs5
-rw-r--r--OpenSim/OpenSim.RegionServer/world/World.cs16
3 files changed, 286 insertions, 234 deletions
diff --git a/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs b/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs
index 7cc39ff..53b14f3 100644
--- a/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs
+++ b/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs
@@ -3,168 +3,54 @@ using System.Collections.Generic;
3using System.Text; 3using System.Text;
4using libsecondlife; 4using libsecondlife;
5using libsecondlife.Packets; 5using libsecondlife.Packets;
6using OpenSim.world;
7using OpenSim.Framework.Interfaces;
8using OpenSim.Framework.Types;
6 9
7namespace OpenSim.world 10namespace OpenSim.RegionServer.world
8{ 11{
9 public delegate void ParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, ClientView remote_client); 12 public delegate void ParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, ClientView remote_client);
10
11 #region Enums
12 public enum ParcelFlags : uint
13 {
14 /// <summary>No flags set</summary>
15 None = 0,
16 /// <summary>Allow avatars to fly (a client-side only restriction)</summary>
17 AllowFly = 1 << 0,
18 /// <summary>Allow foreign scripts to run</summary>
19 AllowOtherScripts = 1 << 1,
20 /// <summary>This parcel is for sale</summary>
21 ForSale = 1 << 2,
22 /// <summary>Allow avatars to create a landmark on this parcel</summary>
23 AllowLandmark = 1 << 3,
24 /// <summary>Allows all avatars to edit the terrain on this parcel</summary>
25 AllowTerraform = 1 << 4,
26 /// <summary>Avatars have health and can take damage on this parcel.
27 /// If set, avatars can be killed and sent home here</summary>
28 AllowDamage = 1 << 5,
29 /// <summary>Foreign avatars can create objects here</summary>
30 CreateObjects = 1 << 6,
31 /// <summary>All objects on this parcel can be purchased</summary>
32 ForSaleObjects = 1 << 7,
33 /// <summary>Access is restricted to a group</summary>
34 UseAccessGroup = 1 << 8,
35 /// <summary>Access is restricted to a whitelist</summary>
36 UseAccessList = 1 << 9,
37 /// <summary>Ban blacklist is enabled</summary>
38 UseBanList = 1 << 10,
39 /// <summary>Unknown</summary>
40 UsePassList = 1 << 11,
41 /// <summary>List this parcel in the search directory</summary>
42 ShowDirectory = 1 << 12,
43 /// <summary>Unknown</summary>
44 AllowDeedToGroup = 1 << 13,
45 /// <summary>Unknown</summary>
46 ContributeWithDeed = 1 << 14,
47 /// <summary>Restrict sounds originating on this parcel to the
48 /// parcel boundaries</summary>
49 SoundLocal = 1 << 15,
50 /// <summary>Objects on this parcel are sold when the land is
51 /// purchsaed</summary>
52 SellParcelObjects = 1 << 16,
53 /// <summary>Allow this parcel to be published on the web</summary>
54 AllowPublish = 1 << 17,
55 /// <summary>The information for this parcel is mature content</summary>
56 MaturePublish = 1 << 18,
57 /// <summary>The media URL is an HTML page</summary>
58 UrlWebPage = 1 << 19,
59 /// <summary>The media URL is a raw HTML string</summary>
60 UrlRawHtml = 1 << 20,
61 /// <summary>Restrict foreign object pushes</summary>
62 RestrictPushObject = 1 << 21,
63 /// <summary>Ban all non identified/transacted avatars</summary>
64 DenyAnonymous = 1 << 22,
65 /// <summary>Ban all identified avatars</summary>
66 DenyIdentified = 1 << 23,
67 /// <summary>Ban all transacted avatars</summary>
68 DenyTransacted = 1 << 24,
69 /// <summary>Allow group-owned scripts to run</summary>
70 AllowGroupScripts = 1 << 25,
71 /// <summary>Allow object creation by group members or group
72 /// objects</summary>
73 CreateGroupObjects = 1 << 26,
74 /// <summary>Allow all objects to enter this parcel</summary>
75 AllowAllObjectEntry = 1 << 27,
76 /// <summary>Only allow group and owner objects to enter this parcel</summary>
77 AllowGroupObjectEntry = 1 << 28,
78 }
79 13
14
15 #region ParcelManager Class
80 /// <summary> 16 /// <summary>
81 /// Parcel ownership status 17 /// Handles Parcel objects and operations requiring information from other Parcel objects (divide, join, etc)
82 /// </summary> 18 /// </summary>
83 public enum ParcelStatus : sbyte 19 public class ParcelManager : OpenSim.Framework.Interfaces.ILocalStorageParcelReceiver
84 { 20 {
85 /// <summary>Eh?</summary>
86 None = -1,
87 /// <summary>Land is owned</summary>
88 Leased = 0,
89 /// <summary>Land is for sale</summary>
90 LeasePending = 1,
91 /// <summary>Land is public</summary>
92 Abandoned = 2
93 }
94 21
95 public enum ParcelCategory : sbyte
96 {
97 /// <summary>No assigned category</summary>
98 None = 0,
99 /// <summary></summary>
100 Linden,
101 /// <summary></summary>
102 Adult,
103 /// <summary></summary>
104 Arts,
105 /// <summary></summary>
106 Business,
107 /// <summary></summary>
108 Educational,
109 /// <summary></summary>
110 Gaming,
111 /// <summary></summary>
112 Hangout,
113 /// <summary></summary>
114 Newcomer,
115 /// <summary></summary>
116 Park,
117 /// <summary></summary>
118 Residential,
119 /// <summary></summary>
120 Shopping,
121 /// <summary></summary>
122 Stage,
123 /// <summary></summary>
124 Other,
125 /// <summary>Not an actual category, only used for queries</summary>
126 Any = -1
127 }
128
129 #endregion
130
131 #region ParcelManager Class
132 public class ParcelManager
133 {
134
135 #region Constants 22 #region Constants
136 //Parcel types set with flags in ParcelOverlay. 23 //Parcel types set with flags in ParcelOverlay.
137 //Only one of these can be used. 24 //Only one of these can be used.
138 public static byte PARCEL_TYPE_PUBLIC = (byte)0; //Equals 00000000 25 public static byte PARCEL_TYPE_PUBLIC = (byte)0; //Equals 00000000
139 public static byte PARCEL_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001 26 public static byte PARCEL_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001
140 public static byte PARCEL_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010 27 public static byte PARCEL_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010
141 public static byte PARCEL_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011 28 public static byte PARCEL_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011
142 public static byte PARCEL_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100 29 public static byte PARCEL_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100
143 public static byte PARCEL_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101 30 public static byte PARCEL_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101
144 31
145 32
146 //Flags that when set, a border on the given side will be placed 33 //Flags that when set, a border on the given side will be placed
147 //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) 34 //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)
148 //This took forever to figure out -- jeesh. /blame LL for even having to send these 35 //This took forever to figure out -- jeesh. /blame LL for even having to send these
149 public static byte PARCEL_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000 36 public static byte PARCEL_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000
150 public static byte PARCEL_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000 37 public static byte PARCEL_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000
151 38
152 #endregion 39 #endregion
153 40
154 #region Member Variables 41 #region Member Variables
155 private List<Parcel> parcelList; 42 public Dictionary<int, Parcel> parcelList = new Dictionary<int, Parcel>();
156 private static World m_world; 43 private int lastParcelLocalID = -1;
44 private int[,] parcelIDList = new int[64, 64];
45
46 private static World m_world;
157 #endregion 47 #endregion
158 48
159 #region Constructors 49 #region Constructors
160 public ParcelManager(World world) 50 public ParcelManager(World world)
161 { 51 {
162 parcelList = new List<Parcel>(); 52
163 m_world = world; 53 m_world = world;
164
165 //NOTE: This is temporary until I get to storing the parcels out of memory
166 //This should later only be for new simulators
167 resetSimParcels();
168 Console.WriteLine("Created ParcelManager Object"); 54 Console.WriteLine("Created ParcelManager Object");
169 55
170 56
@@ -173,38 +59,112 @@ namespace OpenSim.world
173 59
174 #region Member Functions 60 #region Member Functions
175 61
176 #region Parcel Add/Remove/Get 62 #region Parcel From Storage Functions
177 public void addParcel(Parcel new_parcel) 63 public void ParcelFromStorage(ParcelData data)
178 { 64 {
179 parcelList.Add(new_parcel); 65 Parcel new_parcel = new Parcel(data.ownerID, data.isGroupOwned, m_world);
66 new_parcel.parcelData = data;
67 new_parcel.setParcelBitmapFromByteArray();
68
69 this.addParcel(new_parcel);
180 } 70 }
181 public void removeParcel(Parcel old_parcel) 71
72 public void NoParcelDataFromStorage()
182 { 73 {
183 parcelList.Remove(old_parcel); 74 this.resetSimParcels();
184 } 75 }
185 public Parcel getParcel(int x, int y) 76 #endregion
77
78 #region Parcel Add/Remove/Get/Create
79 /// <summary>
80 /// Creates a basic Parcel object without an owner (a zeroed key)
81 /// </summary>
82 /// <returns></returns>
83 public Parcel createBaseParcel()
84 {
85 return new Parcel(new LLUUID(), false, m_world);
86 }
87
88 /// <summary>
89 /// Adds a parcel to the stored list and adds them to the parcelIDList to what they own
90 /// </summary>
91 /// <param name="new_parcel">The parcel being added</param>
92 public void addParcel(Parcel new_parcel)
93 {
94 lastParcelLocalID++;
95 new_parcel.parcelData.localID = lastParcelLocalID;
96 parcelList.Add(lastParcelLocalID, new_parcel);
97
98
99 bool[,] parcelBitmap = new_parcel.getParcelBitmap();
100 int x, y;
101 for (x = 0; x < 64; x++)
102 {
103 for (y = 0; y < 64; y++)
104 {
105 if (parcelBitmap[x, y])
106 {
107 parcelIDList[x, y] = lastParcelLocalID;
108 }
109 }
110 }
111 }
112 /// <summary>
113 /// Removes a parcel from the list. Will not remove if local_id is still owning an area in parcelIDList
114 /// </summary>
115 /// <param name="local_id">Parcel.localID of the parcel to remove.</param>
116 public void removeParcel(int local_id)
186 { 117 {
187 int searchParcel; 118 int x, y;
188 for(searchParcel = 0; searchParcel < this.parcelList.Count; searchParcel++) 119 for (x = 0; x < 64; x++)
189 { 120 {
190 if(parcelList[searchParcel].containsPoint(x,y)) 121 for (y = 0; y < 64; y++)
191 { 122 {
192 return this.parcelList[searchParcel]; 123 if (parcelIDList[x, y] == local_id)
124 {
125 throw new Exception("Could not remove parcel. Still being used at " + x + ", " + y);
126 }
193 } 127 }
194 } 128 }
195 throw new Exception("Error: Parcel not found at point " + x + ", " + y); 129 parcelList.Remove(local_id);
130 }
131 /// <summary>
132 /// Get the parcel at the specified point
133 /// </summary>
134 /// <param name="x">Value between 0 - 256 on the x axis of the point</param>
135 /// <param name="y">Value between 0 - 256 on the y axis of the point</param>
136 /// <returns>Parcel at the point supplied</returns>
137 public Parcel getParcel(int x, int y)
138 {
139 if (x > 256 || y > 256 || x < 0 || y < 0)
140 {
141 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
142 }
143 else
144 {
145 return parcelList[parcelIDList[x / 4, y / 4]];
146 }
196 147
197 } 148 }
198 #endregion 149 #endregion
199 150
200 #region Parcel Modification 151 #region Parcel Modification
152 /// <summary>
153 /// Subdivides a parcel
154 /// </summary>
155 /// <param name="start_x">West Point</param>
156 /// <param name="start_y">South Point</param>
157 /// <param name="end_x">East Point</param>
158 /// <param name="end_y">North Point</param>
159 /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param>
160 /// <returns>Returns true if successful</returns>
201 public bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) 161 public bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
202 { 162 {
203 //First, lets loop through the points and make sure they are all in the same parcel 163 //First, lets loop through the points and make sure they are all in the same parcel
204 //Get the parcel at start 164 //Get the parcel at start
205 Parcel startParcel = getParcel(start_x, start_y); 165 Parcel startParcel = getParcel(start_x, start_y);
206 if(startParcel == null) return false; //No such parcel at the beginning 166 if (startParcel == null) return false; //No such parcel at the beginning
207 167
208 //Loop through the points 168 //Loop through the points
209 try 169 try
210 { 170 {
@@ -228,7 +188,7 @@ namespace OpenSim.world
228 188
229 //If we are still here, then they are subdividing within one parcel 189 //If we are still here, then they are subdividing within one parcel
230 //Check owner 190 //Check owner
231 if (startParcel.ownerID != attempting_user_id) 191 if (startParcel.parcelData.ownerID != attempting_user_id)
232 { 192 {
233 return false; //They cant do this! 193 return false; //They cant do this!
234 } 194 }
@@ -236,17 +196,25 @@ namespace OpenSim.world
236 //Lets create a new parcel with bitmap activated at that point (keeping the old parcels info) 196 //Lets create a new parcel with bitmap activated at that point (keeping the old parcels info)
237 Parcel newParcel = startParcel; 197 Parcel newParcel = startParcel;
238 newParcel.setParcelBitmap(Parcel.getSquareParcelBitmap(start_x, start_y, end_x, end_y)); 198 newParcel.setParcelBitmap(Parcel.getSquareParcelBitmap(start_x, start_y, end_x, end_y));
239 199
240 //Now, lets set the subdivision area of the original to false 200 //Now, lets set the subdivision area of the original to false
241 int startParcelIndex = parcelList.IndexOf(startParcel); 201 int startParcelIndex = startParcel.parcelData.localID;
242 parcelList[startParcelIndex].setParcelBitmap(Parcel.modifyParcelBitmapSquare(parcelList[startParcelIndex].getParcelBitmap(),start_x,start_y,end_x, end_y,false)); 202 parcelList[startParcelIndex].setParcelBitmap(Parcel.modifyParcelBitmapSquare(parcelList[startParcelIndex].getParcelBitmap(), start_x, start_y, end_x, end_y, false));
243 203
244 //Now add the new parcel 204 //Now add the new parcel
245 addParcel(newParcel); 205 addParcel(newParcel);
246 206
247 return true; 207 return true;
248 } 208 }
249 209 /// <summary>
210 /// Join 2 parcels together
211 /// </summary>
212 /// <param name="start_x">x value in first parcel</param>
213 /// <param name="start_y">y value in first parcel</param>
214 /// <param name="end_x">x value in second parcel</param>
215 /// <param name="end_y">y value in second parcel</param>
216 /// <param name="attempting_user_id">LLUUID of the avatar trying to join the parcels</param>
217 /// <returns>Returns true if successful</returns>
250 public bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) 218 public bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
251 { 219 {
252 //NOTE: The following only connects the parcels in each corner and not all the parcels that are within the selection box! 220 //NOTE: The following only connects the parcels in each corner and not all the parcels that are within the selection box!
@@ -262,11 +230,11 @@ namespace OpenSim.world
262 return false; //Error occured when trying to get the start and end parcels 230 return false; //Error occured when trying to get the start and end parcels
263 } 231 }
264 //Check the parcel owners: 232 //Check the parcel owners:
265 if (startParcel.ownerID != endParcel.ownerID) 233 if (startParcel.parcelData.ownerID != endParcel.parcelData.ownerID)
266 { 234 {
267 return false; 235 return false;
268 } 236 }
269 if (startParcel.ownerID != attempting_user_id) 237 if (startParcel.parcelData.ownerID != attempting_user_id)
270 { 238 {
271 //TODO: Group editing stuff. Avatar owner support for now 239 //TODO: Group editing stuff. Avatar owner support for now
272 return false; 240 return false;
@@ -274,10 +242,10 @@ namespace OpenSim.world
274 242
275 //Same owners! Lets join them 243 //Same owners! Lets join them
276 //Merge them to startParcel 244 //Merge them to startParcel
277 parcelList[parcelList.IndexOf(startParcel)].setParcelBitmap(Parcel.mergeParcelBitmaps(startParcel.getParcelBitmap(),endParcel.getParcelBitmap())); 245 parcelList[startParcel.parcelData.localID].setParcelBitmap(Parcel.mergeParcelBitmaps(startParcel.getParcelBitmap(), endParcel.getParcelBitmap()));
278 246
279 //Remove the old parcel 247 //Remove the old parcel
280 parcelList.Remove(endParcel); 248 parcelList.Remove(endParcel.parcelData.localID);
281 249
282 return true; 250 return true;
283 251
@@ -307,17 +275,17 @@ namespace OpenSim.world
307 byte tempByte = (byte)0; //This represents the byte for the current 4x4 275 byte tempByte = (byte)0; //This represents the byte for the current 4x4
308 Parcel currentParcelBlock = getParcel(x * 4, y * 4); 276 Parcel currentParcelBlock = getParcel(x * 4, y * 4);
309 277
310 if (currentParcelBlock.ownerID == remote_client.AgentID) 278 if (currentParcelBlock.parcelData.ownerID == remote_client.AgentID)
311 { 279 {
312 //Owner Flag 280 //Owner Flag
313 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_OWNED_BY_REQUESTER); 281 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_OWNED_BY_REQUESTER);
314 } 282 }
315 else if (currentParcelBlock.salePrice > 0 && (currentParcelBlock.authBuyerID == LLUUID.Zero || currentParcelBlock.authBuyerID == remote_client.AgentID)) 283 else if (currentParcelBlock.parcelData.salePrice > 0 && (currentParcelBlock.parcelData.authBuyerID == LLUUID.Zero || currentParcelBlock.parcelData.authBuyerID == remote_client.AgentID))
316 { 284 {
317 //Sale Flag 285 //Sale Flag
318 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_IS_FOR_SALE); 286 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_IS_FOR_SALE);
319 } 287 }
320 else if (currentParcelBlock.ownerID == LLUUID.Zero) 288 else if (currentParcelBlock.parcelData.ownerID == LLUUID.Zero)
321 { 289 {
322 //Public Flag 290 //Public Flag
323 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_PUBLIC); 291 tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_PUBLIC);
@@ -369,57 +337,45 @@ namespace OpenSim.world
369 remote_client.OutPacket((Packet)packet); 337 remote_client.OutPacket((Packet)packet);
370 } 338 }
371 #endregion 339 #endregion
340
341 /// <summary>
342 /// Resets the sim to the default parcel (full sim parcel owned by the default user)
343 /// </summary>
372 public void resetSimParcels() 344 public void resetSimParcels()
373 { 345 {
374 //Remove all the parcels in the sim and add a blank, full sim parcel set to public 346 //Remove all the parcels in the sim and add a blank, full sim parcel set to public
375 parcelList.Clear(); 347 parcelList.Clear();
376 Parcel fullSimParcel = new Parcel(LLUUID.Zero, false,m_world); 348 parcelIDList.Initialize();
349 Parcel fullSimParcel = new Parcel(LLUUID.Zero, false, m_world);
377 fullSimParcel.setParcelBitmap(Parcel.basicFullRegionParcelBitmap()); 350 fullSimParcel.setParcelBitmap(Parcel.basicFullRegionParcelBitmap());
378 fullSimParcel.parcelName = "Your Sim Parcel"; 351 fullSimParcel.parcelData.parcelName = "Your Sim Parcel";
379 fullSimParcel.parcelDesc = ""; 352 fullSimParcel.parcelData.parcelDesc = "";
380 LLUUID Agent;
381 int AgentRand = OpenSim.Framework.Utilities.Util.RandomClass.Next(1, 9999);
382 Agent = new LLUUID("99998888-0100-" + AgentRand.ToString("0000") + "-8ec1-0b1d5cd6aead");
383
384 fullSimParcel.ownerID = Agent;
385 fullSimParcel.salePrice = 1;
386 fullSimParcel.parcelFlags = ParcelFlags.ForSale;
387 353
354 fullSimParcel.parcelData.ownerID = LLUUID.Zero;
355 fullSimParcel.parcelData.salePrice = -1;
356 fullSimParcel.parcelData.parcelFlags = libsecondlife.Parcel.ParcelFlags.None;
357 fullSimParcel.parcelData.parcelStatus = libsecondlife.Parcel.ParcelStatus.Abandoned;
388 addParcel(fullSimParcel); 358 addParcel(fullSimParcel);
389 359
390 360
391 } 361 }
392 #endregion 362 #endregion
393 } 363 }
394 #endregion 364 #endregion
395 365
396 366
397 #region Parcel Class 367 #region Parcel Class
368 /// <summary>
369 /// Keeps track of a specific parcel's information
370 /// </summary>
398 public class Parcel 371 public class Parcel
399 { 372 {
400 #region Member Variables 373 #region Member Variables
401 private bool[,] parcelBitmap = new bool[64,64]; 374 public ParcelData parcelData = new ParcelData();
402 public string parcelName = ""; 375 public World m_world;
403 public string parcelDesc = ""; 376
404 public LLUUID ownerID = new LLUUID(); 377 private bool[,] parcelBitmap = new bool[64, 64];
405 public bool isGroupOwned = false; 378
406 public LLVector3 AABBMin = new LLVector3();
407 public LLVector3 AABBMax = new LLVector3();
408 public int area = 0;
409 public uint auctionID = 0; //Unemplemented. If set to 0, not being auctioned
410 public LLUUID authBuyerID = new LLUUID(); //Unemplemented. Authorized Buyer's UUID
411 public ParcelCategory category = new ParcelCategory(); //Unemplemented. Parcel's chosen category
412 public int claimDate = 0; //Unemplemented
413 public int claimPrice = 0; //Unemplemented
414 public LLUUID groupID = new LLUUID(); //Unemplemented
415 public int groupPrims = 0; //Unemplemented
416 public int salePrice = 0; //Unemeplemented. Parcels price.
417 public ParcelStatus parcelStatus = ParcelStatus.None;
418 public ParcelFlags parcelFlags = ParcelFlags.None;
419
420 private int localID;
421 private static int localIDCount = 0;
422 private World m_world;
423 #endregion 379 #endregion
424 380
425 381
@@ -427,11 +383,8 @@ namespace OpenSim.world
427 public Parcel(LLUUID owner_id, bool is_group_owned, World world) 383 public Parcel(LLUUID owner_id, bool is_group_owned, World world)
428 { 384 {
429 m_world = world; 385 m_world = world;
430 ownerID = owner_id; 386 parcelData.ownerID = owner_id;
431 isGroupOwned = is_group_owned; 387 parcelData.isGroupOwned = is_group_owned;
432
433 localID = localIDCount;
434 localIDCount++;
435 388
436 } 389 }
437 #endregion 390 #endregion
@@ -440,6 +393,12 @@ namespace OpenSim.world
440 #region Member Functions 393 #region Member Functions
441 394
442 #region General Functions 395 #region General Functions
396 /// <summary>
397 /// Checks to see if this parcel contains a point
398 /// </summary>
399 /// <param name="x"></param>
400 /// <param name="y"></param>
401 /// <returns>Returns true if the parcel contains the specified point</returns>
443 public bool containsPoint(int x, int y) 402 public bool containsPoint(int x, int y)
444 { 403 {
445 if (x >= 0 && y >= 0 && x <= 256 && x <= 256) 404 if (x >= 0 && y >= 0 && x <= 256 && x <= 256)
@@ -455,39 +414,45 @@ namespace OpenSim.world
455 414
456 415
457 #region Packet Request Handling 416 #region Packet Request Handling
417 /// <summary>
418 /// Sends parcel properties as requested
419 /// </summary>
420 /// <param name="sequence_id">ID sent by client for them to keep track of</param>
421 /// <param name="snap_selection">Bool sent by client for them to use</param>
422 /// <param name="remote_client">Object representing the client</param>
458 public void sendParcelProperties(int sequence_id, bool snap_selection, ClientView remote_client) 423 public void sendParcelProperties(int sequence_id, bool snap_selection, ClientView remote_client)
459 { 424 {
460 425
461 ParcelPropertiesPacket updatePacket = new ParcelPropertiesPacket(); 426 ParcelPropertiesPacket updatePacket = new ParcelPropertiesPacket();
462 updatePacket.ParcelData.AABBMax = AABBMax; 427 updatePacket.ParcelData.AABBMax = parcelData.AABBMax;
463 updatePacket.ParcelData.AABBMin = AABBMin; 428 updatePacket.ParcelData.AABBMin = parcelData.AABBMin;
464 updatePacket.ParcelData.Area = this.area; 429 updatePacket.ParcelData.Area = this.parcelData.area;
465 updatePacket.ParcelData.AuctionID = this.auctionID; 430 updatePacket.ParcelData.AuctionID = this.parcelData.auctionID;
466 updatePacket.ParcelData.AuthBuyerID = this.authBuyerID; //unemplemented 431 updatePacket.ParcelData.AuthBuyerID = this.parcelData.authBuyerID; //unemplemented
467 432
468 updatePacket.ParcelData.Bitmap = this.convertParcelBitmapToBytes(); 433 updatePacket.ParcelData.Bitmap = this.convertParcelBitmapToBytes();
469 434
470 updatePacket.ParcelData.Desc = libsecondlife.Helpers.StringToField(this.parcelDesc); 435 updatePacket.ParcelData.Desc = libsecondlife.Helpers.StringToField(this.parcelData.parcelDesc);
471 updatePacket.ParcelData.Category = (byte)this.category; 436 updatePacket.ParcelData.Category = (byte)this.parcelData.category;
472 updatePacket.ParcelData.ClaimDate = this.claimDate; 437 updatePacket.ParcelData.ClaimDate = this.parcelData.claimDate;
473 updatePacket.ParcelData.ClaimPrice = this.claimPrice; 438 updatePacket.ParcelData.ClaimPrice = this.parcelData.claimPrice;
474 updatePacket.ParcelData.GroupID = this.groupID; 439 updatePacket.ParcelData.GroupID = this.parcelData.groupID;
475 updatePacket.ParcelData.GroupPrims = this.groupPrims; 440 updatePacket.ParcelData.GroupPrims = this.parcelData.groupPrims;
476 updatePacket.ParcelData.IsGroupOwned = this.isGroupOwned; 441 updatePacket.ParcelData.IsGroupOwned = this.parcelData.isGroupOwned;
477 updatePacket.ParcelData.LandingType = (byte)0; //unemplemented 442 updatePacket.ParcelData.LandingType = (byte)0; //unemplemented
478 updatePacket.ParcelData.LocalID = (byte)this.localID; 443 updatePacket.ParcelData.LocalID = (byte)this.parcelData.localID;
479 updatePacket.ParcelData.MaxPrims = 1000; //unemplemented 444 updatePacket.ParcelData.MaxPrims = 1000; //unemplemented
480 updatePacket.ParcelData.MediaAutoScale = (byte)0; //unemplemented 445 updatePacket.ParcelData.MediaAutoScale = (byte)0; //unemplemented
481 updatePacket.ParcelData.MediaID = LLUUID.Zero; //unemplemented 446 updatePacket.ParcelData.MediaID = LLUUID.Zero; //unemplemented
482 updatePacket.ParcelData.MediaURL = Helpers.StringToField(""); //unemplemented 447 updatePacket.ParcelData.MediaURL = Helpers.StringToField(""); //unemplemented
483 updatePacket.ParcelData.MusicURL = Helpers.StringToField(""); //unemplemented 448 updatePacket.ParcelData.MusicURL = Helpers.StringToField(""); //unemplemented
484 updatePacket.ParcelData.Name = Helpers.StringToField(this.parcelName); 449 updatePacket.ParcelData.Name = Helpers.StringToField(this.parcelData.parcelName);
485 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented 450 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented
486 updatePacket.ParcelData.OtherCount = 0; //unemplemented 451 updatePacket.ParcelData.OtherCount = 0; //unemplemented
487 updatePacket.ParcelData.OtherPrims = 0; //unemplented 452 updatePacket.ParcelData.OtherPrims = 0; //unemplented
488 updatePacket.ParcelData.OwnerID = this.ownerID; 453 updatePacket.ParcelData.OwnerID = this.parcelData.ownerID;
489 updatePacket.ParcelData.OwnerPrims = 0; //unemplemented 454 updatePacket.ParcelData.OwnerPrims = 0; //unemplemented
490 updatePacket.ParcelData.ParcelFlags = (uint)this.parcelFlags; //unemplemented 455 updatePacket.ParcelData.ParcelFlags = (uint)this.parcelData.parcelFlags; //unemplemented
491 updatePacket.ParcelData.ParcelPrimBonus = (float)1.0; //unemplemented 456 updatePacket.ParcelData.ParcelPrimBonus = (float)1.0; //unemplemented
492 updatePacket.ParcelData.PassHours = (float)0.0; //unemplemented 457 updatePacket.ParcelData.PassHours = (float)0.0; //unemplemented
493 updatePacket.ParcelData.PassPrice = 0; //unemeplemented 458 updatePacket.ParcelData.PassPrice = 0; //unemeplemented
@@ -498,7 +463,7 @@ namespace OpenSim.world
498 updatePacket.ParcelData.RegionPushOverride = true; //unemplemented 463 updatePacket.ParcelData.RegionPushOverride = true; //unemplemented
499 updatePacket.ParcelData.RentPrice = 0; //?? 464 updatePacket.ParcelData.RentPrice = 0; //??
500 updatePacket.ParcelData.RequestResult = 0;//?? 465 updatePacket.ParcelData.RequestResult = 0;//??
501 updatePacket.ParcelData.SalePrice = this.salePrice; //unemplemented 466 updatePacket.ParcelData.SalePrice = this.parcelData.salePrice; //unemplemented
502 updatePacket.ParcelData.SelectedPrims = 0; //unemeplemented 467 updatePacket.ParcelData.SelectedPrims = 0; //unemeplemented
503 updatePacket.ParcelData.SelfCount = 0;//unemplemented 468 updatePacket.ParcelData.SelfCount = 0;//unemplemented
504 updatePacket.ParcelData.SequenceID = sequence_id; 469 updatePacket.ParcelData.SequenceID = sequence_id;
@@ -506,17 +471,20 @@ namespace OpenSim.world
506 updatePacket.ParcelData.SimWideTotalPrims = 0; //unemplemented 471 updatePacket.ParcelData.SimWideTotalPrims = 0; //unemplemented
507 updatePacket.ParcelData.SnapSelection = snap_selection; //Bleh - not important yet 472 updatePacket.ParcelData.SnapSelection = snap_selection; //Bleh - not important yet
508 updatePacket.ParcelData.SnapshotID = LLUUID.Zero; //Unemplemented 473 updatePacket.ParcelData.SnapshotID = LLUUID.Zero; //Unemplemented
509 updatePacket.ParcelData.Status = (byte)this.parcelStatus; //?? 474 updatePacket.ParcelData.Status = (byte)this.parcelData.parcelStatus; //??
510 updatePacket.ParcelData.TotalPrims = 0; //unemplemented 475 updatePacket.ParcelData.TotalPrims = 0; //unemplemented
511 updatePacket.ParcelData.UserLocation = LLVector3.Zero; //unemplemented 476 updatePacket.ParcelData.UserLocation = LLVector3.Zero; //unemplemented
512 updatePacket.ParcelData.UserLookAt = LLVector3.Zero; //unemeplemented 477 updatePacket.ParcelData.UserLookAt = LLVector3.Zero; //unemeplemented
513 478
514 remote_client.OutPacket((Packet)updatePacket); 479 remote_client.OutPacket((Packet)updatePacket);
515 } 480 }
516 #endregion 481 #endregion
517 482
518 483
519 #region Update Functions 484 #region Update Functions
485 /// <summary>
486 /// Updates the AABBMin and AABBMax values after area/shape modification of parcel
487 /// </summary>
520 private void updateAABBAndAreaValues() 488 private void updateAABBAndAreaValues()
521 { 489 {
522 int min_x = 64; 490 int min_x = 64;
@@ -539,14 +507,27 @@ namespace OpenSim.world
539 } 507 }
540 } 508 }
541 } 509 }
542 this.AABBMin = new LLVector3((float)(min_x * 4), (float)(min_y * 4), m_world.Terrain[(min_x * 4), (min_y * 4)]); 510 this.parcelData.AABBMin = new LLVector3((float)(min_x * 4), (float)(min_y * 4), m_world.Terrain[(min_x * 4), (min_y * 4)]);
543 this.AABBMax = new LLVector3((float)(max_x * 4), (float)(max_y * 4), m_world.Terrain[(max_x * 4), (max_y * 4)]); 511 this.parcelData.AABBMax = new LLVector3((float)(max_x * 4), (float)(max_y * 4), m_world.Terrain[(max_x * 4), (max_y * 4)]);
544 this.area = tempArea; 512 this.parcelData.area = tempArea;
513 }
514
515 public void updateParcelBitmapByteArray()
516 {
517 parcelData.parcelBitmapByteArray = convertParcelBitmapToBytes();
518 }
519 public void setParcelBitmapFromByteArray()
520 {
521 parcelBitmap = convertBytesToParcelBitmap();
545 } 522 }
546 #endregion 523 #endregion
547 524
548 525
549 #region Parcel Bitmap Functions 526 #region Parcel Bitmap Functions
527 /// <summary>
528 /// Sets the parcel's bitmap manually
529 /// </summary>
530 /// <param name="bitmap">64x64 block representing where this parcel is on a map</param>
550 public void setParcelBitmap(bool[,] bitmap) 531 public void setParcelBitmap(bool[,] bitmap)
551 { 532 {
552 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) 533 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
@@ -559,23 +540,32 @@ namespace OpenSim.world
559 //Valid: Lets set it 540 //Valid: Lets set it
560 this.parcelBitmap = bitmap; 541 this.parcelBitmap = bitmap;
561 updateAABBAndAreaValues(); 542 updateAABBAndAreaValues();
543 updateParcelBitmapByteArray();
562 } 544 }
563 } 545 }
546 /// <summary>
547 /// Gets the parcels bitmap manually
548 /// </summary>
549 /// <returns></returns>
564 public bool[,] getParcelBitmap() 550 public bool[,] getParcelBitmap()
565 { 551 {
566 return parcelBitmap; 552 return parcelBitmap;
567 } 553 }
554 /// <summary>
555 /// Converts the parcel bitmap to a packet friendly byte array
556 /// </summary>
557 /// <returns></returns>
568 private byte[] convertParcelBitmapToBytes() 558 private byte[] convertParcelBitmapToBytes()
569 { 559 {
570 byte[] tempConvertArr = new byte[64 * 64 / 8]; 560 byte[] tempConvertArr = new byte[64 * 64 / 8];
571 byte tempByte = 0; 561 byte tempByte = 0;
572 int x, y,i, byteNum = 0; 562 int x, y, i, byteNum = 0;
573 i = 0; 563 i = 0;
574 for (x = 0; x < 64; x++) 564 for (y = 0; y < 64; y++)
575 { 565 {
576 for (y = 0; y < 64; y++) 566 for (x = 0; x < 64; x++)
577 { 567 {
578 tempByte = Convert.ToByte(tempByte | Convert.ToByte(parcelBitmap[x,y]) << (i++ % 8)); 568 tempByte = Convert.ToByte(tempByte | Convert.ToByte(parcelBitmap[x, y]) << (i++ % 8));
579 if (i % 8 == 0) 569 if (i % 8 == 0)
580 { 570 {
581 tempConvertArr[byteNum] = tempByte; 571 tempConvertArr[byteNum] = tempByte;
@@ -585,14 +575,44 @@ namespace OpenSim.world
585 } 575 }
586 } 576 }
587 } 577 }
588 tempByte.ToString();
589 return tempConvertArr; 578 return tempConvertArr;
590 } 579 }
591 580
581 private bool[,] convertBytesToParcelBitmap()
582 {
583 bool[,] tempConvertMap = new bool[64, 64];
584
585 byte tempByte = 0;
586 int x = 0, y = 0, i = 0, bitNum = 0;
587 for(i = 0; i < 512; i++)
588 {
589 tempByte = parcelData.parcelBitmapByteArray[i];
590 for(bitNum = 7; bitNum >= 0; bitNum--)
591 {
592 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte)1);
593 tempConvertMap[x, y] = bit;
594 if (x >= 64) y++;
595 }
596 }
597 return tempConvertMap;
598 }
599 /// <summary>
600 /// Full sim parcel creation
601 /// </summary>
602 /// <returns></returns>
592 public static bool[,] basicFullRegionParcelBitmap() 603 public static bool[,] basicFullRegionParcelBitmap()
593 { 604 {
594 return getSquareParcelBitmap(0, 0, 256, 256); 605 return getSquareParcelBitmap(0, 0, 256, 256);
595 } 606 }
607
608 /// <summary>
609 /// Used to modify the bitmap between the x and y points. Points use 64 scale
610 /// </summary>
611 /// <param name="start_x"></param>
612 /// <param name="start_y"></param>
613 /// <param name="end_x"></param>
614 /// <param name="end_y"></param>
615 /// <returns></returns>
596 public static bool[,] getSquareParcelBitmap(int start_x, int start_y, int end_x, int end_y) 616 public static bool[,] getSquareParcelBitmap(int start_x, int start_y, int end_x, int end_y)
597 { 617 {
598 618
@@ -602,6 +622,17 @@ namespace OpenSim.world
602 tempBitmap = modifyParcelBitmapSquare(tempBitmap, start_x, start_y, end_x, end_x, true); 622 tempBitmap = modifyParcelBitmapSquare(tempBitmap, start_x, start_y, end_x, end_x, true);
603 return tempBitmap; 623 return tempBitmap;
604 } 624 }
625
626 /// <summary>
627 /// Change a parcel's bitmap at within a square and set those points to a specific value
628 /// </summary>
629 /// <param name="parcel_bitmap"></param>
630 /// <param name="start_x"></param>
631 /// <param name="start_y"></param>
632 /// <param name="end_x"></param>
633 /// <param name="end_y"></param>
634 /// <param name="set_value"></param>
635 /// <returns></returns>
605 public static bool[,] modifyParcelBitmapSquare(bool[,] parcel_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value) 636 public static bool[,] modifyParcelBitmapSquare(bool[,] parcel_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value)
606 { 637 {
607 if (parcel_bitmap.GetLength(0) != 64 || parcel_bitmap.GetLength(1) != 64 || parcel_bitmap.Rank != 2) 638 if (parcel_bitmap.GetLength(0) != 64 || parcel_bitmap.GetLength(1) != 64 || parcel_bitmap.Rank != 2)
@@ -624,6 +655,12 @@ namespace OpenSim.world
624 } 655 }
625 return parcel_bitmap; 656 return parcel_bitmap;
626 } 657 }
658 /// <summary>
659 /// Join the true values of 2 bitmaps together
660 /// </summary>
661 /// <param name="bitmap_base"></param>
662 /// <param name="bitmap_add"></param>
663 /// <returns></returns>
627 public static bool[,] mergeParcelBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) 664 public static bool[,] mergeParcelBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
628 { 665 {
629 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) 666 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
@@ -642,7 +679,7 @@ namespace OpenSim.world
642 { 679 {
643 for (y = 0; y < 64; y++) 680 for (y = 0; y < 64; y++)
644 { 681 {
645 if (bitmap_add[x,y]) 682 if (bitmap_add[x, y])
646 { 683 {
647 bitmap_base[x, y] = true; 684 bitmap_base[x, y] = true;
648 } 685 }
@@ -653,6 +690,10 @@ namespace OpenSim.world
653 #endregion 690 #endregion
654 691
655 #endregion 692 #endregion
693
694
656 } 695 }
657 #endregion 696 #endregion
697
698
658} 699}
diff --git a/OpenSim/OpenSim.RegionServer/world/World.PacketHandlers.cs b/OpenSim/OpenSim.RegionServer/world/World.PacketHandlers.cs
index 74b8e9d..8924773 100644
--- a/OpenSim/OpenSim.RegionServer/world/World.PacketHandlers.cs
+++ b/OpenSim/OpenSim.RegionServer/world/World.PacketHandlers.cs
@@ -10,6 +10,7 @@ using OpenSim.Framework.Terrain;
10using OpenSim.Framework.Inventory; 10using OpenSim.Framework.Inventory;
11using OpenSim.Framework.Utilities; 11using OpenSim.Framework.Utilities;
12using OpenSim.Assets; 12using OpenSim.Assets;
13using OpenSim.RegionServer.world;
13 14
14namespace OpenSim.world 15namespace OpenSim.world
15{ 16{
@@ -296,7 +297,7 @@ namespace OpenSim.world
296 void ParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, ClientView remote_client) 297 void ParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, ClientView remote_client)
297 { 298 {
298 //Get the parcels within the bounds 299 //Get the parcels within the bounds
299 List<Parcel> temp = new List<Parcel>(); 300 List<OpenSim.RegionServer.world.Parcel> temp = new List<OpenSim.RegionServer.world.Parcel>();
300 int x, y; 301 int x, y;
301 int inc_x = end_x - start_x; 302 int inc_x = end_x - start_x;
302 int inc_y = end_y - start_y; 303 int inc_y = end_y - start_y;
@@ -304,7 +305,7 @@ namespace OpenSim.world
304 { 305 {
305 for(y = 0; y < inc_y; y++) 306 for(y = 0; y < inc_y; y++)
306 { 307 {
307 Parcel currentParcel = parcelManager.getParcel(start_x + x,start_y + y); 308 OpenSim.RegionServer.world.Parcel currentParcel = parcelManager.getParcel(start_x + x, start_y + y);
308 if(!temp.Contains(currentParcel)) 309 if(!temp.Contains(currentParcel))
309 { 310 {
310 temp.Add(currentParcel); 311 temp.Add(currentParcel);
diff --git a/OpenSim/OpenSim.RegionServer/world/World.cs b/OpenSim/OpenSim.RegionServer/world/World.cs
index d2a13ca..92de6f0 100644
--- a/OpenSim/OpenSim.RegionServer/world/World.cs
+++ b/OpenSim/OpenSim.RegionServer/world/World.cs
@@ -35,7 +35,7 @@ namespace OpenSim.world
35 private Dictionary<string, ScriptFactory> m_scripts; 35 private Dictionary<string, ScriptFactory> m_scripts;
36 private Mutex updateLock; 36 private Mutex updateLock;
37 public string m_datastore; 37 public string m_datastore;
38 public ParcelManager parcelManager; 38 public OpenSim.RegionServer.world.ParcelManager parcelManager;
39 39
40 #region Properties 40 #region Properties
41 public PhysicsScene PhysScene 41 public PhysicsScene PhysScene
@@ -86,7 +86,6 @@ namespace OpenSim.world
86 Avatar.LoadAnims(); 86 Avatar.LoadAnims();
87 this.SetDefaultScripts(); 87 this.SetDefaultScripts();
88 this.LoadScriptEngines(); 88 this.LoadScriptEngines();
89 parcelManager = new ParcelManager(this);
90 89
91 } 90 }
92 catch (Exception e) 91 catch (Exception e)
@@ -252,6 +251,17 @@ namespace OpenSim.world
252 Entities[UUID].BackUp(); 251 Entities[UUID].BackUp();
253 } 252 }
254 253
254
255 //Parcel backup routines. Yay!
256 ParcelData[] parcels = new ParcelData[parcelManager.parcelList.Count];
257 int i;
258 for(i = 0; i < parcelManager.parcelList.Count; i++)
259 {
260 parcels[i] = parcelManager.parcelList[i].parcelData;
261 }
262 localStorage.SaveParcels(parcels);
263
264
255 // Backup successful 265 // Backup successful
256 return true; 266 return true;
257 } 267 }
@@ -576,7 +586,7 @@ namespace OpenSim.world
576 agentClient.OnUpdatePrimScale += new ClientView.UpdatePrimVector(this.UpdatePrimScale); 586 agentClient.OnUpdatePrimScale += new ClientView.UpdatePrimVector(this.UpdatePrimScale);
577 agentClient.OnDeRezObject += new ClientView.GenericCall4(this.DeRezObject); 587 agentClient.OnDeRezObject += new ClientView.GenericCall4(this.DeRezObject);
578 588
579 agentClient.OnParcelPropertiesRequest += new ParcelPropertiesRequest(ParcelPropertiesRequest); 589 agentClient.OnParcelPropertiesRequest += new OpenSim.RegionServer.world.ParcelPropertiesRequest(ParcelPropertiesRequest);
580 Avatar newAvatar = null; 590 Avatar newAvatar = null;
581 try 591 try
582 { 592 {