aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/LandManagement/Land.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/LandManagement/LandObject.cs (renamed from OpenSim/Region/Environment/LandManagement/Land.cs)1721
1 files changed, 879 insertions, 842 deletions
diff --git a/OpenSim/Region/Environment/LandManagement/Land.cs b/OpenSim/Region/Environment/Modules/LandManagement/LandObject.cs
index 5b84103..4e2fbd3 100644
--- a/OpenSim/Region/Environment/LandManagement/Land.cs
+++ b/OpenSim/Region/Environment/Modules/LandManagement/LandObject.cs
@@ -1,842 +1,879 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using libsecondlife; 30using libsecondlife;
31using libsecondlife.Packets; 31using libsecondlife.Packets;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Console; 33using OpenSim.Framework.Console;
34using OpenSim.Region.Environment.Scenes; 34using OpenSim.Region.Environment.Scenes;
35using OpenSim.Region.Environment.Interfaces; 35using OpenSim.Region.Environment.Interfaces;
36 36
37namespace OpenSim.Region.Environment.LandManagement 37namespace OpenSim.Region.Environment.Modules.LandManagement
38{ 38{
39 39
40 #region Parcel Class 40 #region LandObject Class
41 41
42 /// <summary> 42 /// <summary>
43 /// Keeps track of a specific piece of land's information 43 /// Keeps track of a specific piece of land's information
44 /// </summary> 44 /// </summary>
45 public class Land 45 public class LandObject : ILandObject
46 { 46 {
47 #region Member Variables 47 #region Member Variables
48 48
49 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 public LandData landData = new LandData(); 51 protected LandData m_landData = new LandData();
52 public List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); 52 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
53 public Scene m_scene; 53 protected Scene m_scene;
54 54
55 private bool[,] landBitmap = new bool[64,64]; 55 private bool[,] m_landBitmap = new bool[64,64];
56 56
57 #endregion 57 public bool[,] landBitmap
58 58 {
59 #region Constructors 59 get
60 60 {
61 public Land(LLUUID owner_id, bool is_group_owned, Scene scene) 61 return m_landBitmap;
62 { 62 }
63 m_scene = scene; 63 set
64 landData.ownerID = owner_id; 64 {
65 landData.isGroupOwned = is_group_owned; 65 m_landBitmap = value;
66 } 66 }
67 67 }
68 #endregion 68
69 69 #endregion
70 #region Member Functions 70
71 71 #region ILandObject Members
72 #region General Functions 72
73 73 public LandData landData
74 /// <summary> 74 {
75 /// Checks to see if this land object contains a point 75 get
76 /// </summary> 76 {
77 /// <param name="x"></param> 77 return m_landData;
78 /// <param name="y"></param> 78 }
79 /// <returns>Returns true if the piece of land contains the specified point</returns> 79
80 public bool containsPoint(int x, int y) 80 set
81 { 81 {
82 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize) 82 m_landData = value;
83 { 83 }
84 return (landBitmap[x/4, y/4] == true); 84 }
85 } 85
86 else 86 public LLUUID regionUUID
87 { 87 {
88 return false; 88 get { return m_scene.RegionInfo.RegionID; }
89 } 89 }
90 } 90
91 91 #endregion
92 public Land Copy() 92
93 { 93
94 Land newLand = new Land(landData.ownerID, landData.isGroupOwned, m_scene); 94 #region Constructors
95 95
96 //Place all new variables here! 96 public LandObject(LLUUID owner_id, bool is_group_owned, Scene scene)
97 newLand.landBitmap = (bool[,]) (landBitmap.Clone()); 97 {
98 newLand.landData = landData.Copy(); 98 m_scene = scene;
99 99 landData.ownerID = owner_id;
100 return newLand; 100 landData.isGroupOwned = is_group_owned;
101 } 101 }
102 102
103 #endregion 103 #endregion
104 104
105 #region Packet Request Handling 105 #region Member Functions
106 106
107 /// <summary> 107 #region General Functions
108 /// Sends land properties as requested 108
109 /// </summary> 109 /// <summary>
110 /// <param name="sequence_id">ID sent by client for them to keep track of</param> 110 /// Checks to see if this land object contains a point
111 /// <param name="snap_selection">Bool sent by client for them to use</param> 111 /// </summary>
112 /// <param name="remote_client">Object representing the client</param> 112 /// <param name="x"></param>
113 public void sendLandProperties(int sequence_id, bool snap_selection, int request_result, 113 /// <param name="y"></param>
114 IClientAPI remote_client) 114 /// <returns>Returns true if the piece of land contains the specified point</returns>
115 { 115 public bool containsPoint(int x, int y)
116 ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties); 116 {
117 // TODO: don't create new blocks if recycling an old packet 117 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize)
118 118 {
119 updatePacket.ParcelData.AABBMax = landData.AABBMax; 119 return (landBitmap[x/4, y/4] == true);
120 updatePacket.ParcelData.AABBMin = landData.AABBMin; 120 }
121 updatePacket.ParcelData.Area = landData.area; 121 else
122 updatePacket.ParcelData.AuctionID = landData.auctionID; 122 {
123 updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented 123 return false;
124 124 }
125 updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray; 125 }
126 126
127 updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc); 127 public ILandObject Copy()
128 updatePacket.ParcelData.Category = (byte) landData.category; 128 {
129 updatePacket.ParcelData.ClaimDate = landData.claimDate; 129 ILandObject newLand = new LandObject(landData.ownerID, landData.isGroupOwned, m_scene);
130 updatePacket.ParcelData.ClaimPrice = landData.claimPrice; 130
131 updatePacket.ParcelData.GroupID = landData.groupID; 131 //Place all new variables here!
132 updatePacket.ParcelData.GroupPrims = landData.groupPrims; 132 newLand.landBitmap = (bool[,]) (landBitmap.Clone());
133 updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned; 133 newLand.landData = landData.Copy();
134 updatePacket.ParcelData.LandingType = (byte) landData.landingType; 134
135 updatePacket.ParcelData.LocalID = landData.localID; 135 return newLand;
136 if (landData.area > 0) 136 }
137 { 137
138 updatePacket.ParcelData.MaxPrims = 138 #endregion
139 Convert.ToInt32( 139
140 Math.Round((Convert.ToDecimal(landData.area)/Convert.ToDecimal(65536))*15000* 140 #region Packet Request Handling
141 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); 141
142 } 142 /// <summary>
143 else 143 /// Sends land properties as requested
144 { 144 /// </summary>
145 updatePacket.ParcelData.MaxPrims = 0; 145 /// <param name="sequence_id">ID sent by client for them to keep track of</param>
146 } 146 /// <param name="snap_selection">Bool sent by client for them to use</param>
147 updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale; 147 /// <param name="remote_client">Object representing the client</param>
148 updatePacket.ParcelData.MediaID = landData.mediaID; 148 public void sendLandProperties(int sequence_id, bool snap_selection, int request_result,
149 updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL); 149 IClientAPI remote_client)
150 updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL); 150 {
151 updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName); 151 ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties);
152 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented 152 // TODO: don't create new blocks if recycling an old packet
153 updatePacket.ParcelData.OtherCount = 0; //unemplemented 153
154 updatePacket.ParcelData.OtherPrims = landData.otherPrims; 154 updatePacket.ParcelData.AABBMax = landData.AABBMax;
155 updatePacket.ParcelData.OwnerID = landData.ownerID; 155 updatePacket.ParcelData.AABBMin = landData.AABBMin;
156 updatePacket.ParcelData.OwnerPrims = landData.ownerPrims; 156 updatePacket.ParcelData.Area = landData.area;
157 updatePacket.ParcelData.ParcelFlags = landData.landFlags; 157 updatePacket.ParcelData.AuctionID = landData.auctionID;
158 updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor; 158 updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented
159 updatePacket.ParcelData.PassHours = landData.passHours; 159
160 updatePacket.ParcelData.PassPrice = landData.passPrice; 160 updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray;
161 updatePacket.ParcelData.PublicCount = 0; //unemplemented 161
162 162 updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc);
163 uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags; 163 updatePacket.ParcelData.Category = (byte) landData.category;
164 updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) > 164 updatePacket.ParcelData.ClaimDate = landData.claimDate;
165 0); 165 updatePacket.ParcelData.ClaimPrice = landData.claimPrice;
166 updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) > 166 updatePacket.ParcelData.GroupID = landData.groupID;
167 0); 167 updatePacket.ParcelData.GroupPrims = landData.groupPrims;
168 updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) > 168 updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned;
169 0); 169 updatePacket.ParcelData.LandingType = (byte) landData.landingType;
170 updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) > 170 updatePacket.ParcelData.LocalID = landData.localID;
171 0); 171 if (landData.area > 0)
172 172 {
173 updatePacket.ParcelData.RentPrice = 0; 173 updatePacket.ParcelData.MaxPrims =
174 updatePacket.ParcelData.RequestResult = request_result; 174 Convert.ToInt32(
175 updatePacket.ParcelData.SalePrice = landData.salePrice; 175 Math.Round((Convert.ToDecimal(landData.area)/Convert.ToDecimal(65536))*15000*
176 updatePacket.ParcelData.SelectedPrims = landData.selectedPrims; 176 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
177 updatePacket.ParcelData.SelfCount = 0; //unemplemented 177 }
178 updatePacket.ParcelData.SequenceID = sequence_id; 178 else
179 if (landData.simwideArea > 0) 179 {
180 { 180 updatePacket.ParcelData.MaxPrims = 0;
181 updatePacket.ParcelData.SimWideMaxPrims = 181 }
182 Convert.ToInt32( 182 updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale;
183 Math.Round((Convert.ToDecimal(landData.simwideArea)/Convert.ToDecimal(65536))*15000* 183 updatePacket.ParcelData.MediaID = landData.mediaID;
184 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); 184 updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL);
185 } 185 updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL);
186 else 186 updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName);
187 { 187 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented
188 updatePacket.ParcelData.SimWideMaxPrims = 0; 188 updatePacket.ParcelData.OtherCount = 0; //unemplemented
189 } 189 updatePacket.ParcelData.OtherPrims = landData.otherPrims;
190 updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims; 190 updatePacket.ParcelData.OwnerID = landData.ownerID;
191 updatePacket.ParcelData.SnapSelection = snap_selection; 191 updatePacket.ParcelData.OwnerPrims = landData.ownerPrims;
192 updatePacket.ParcelData.SnapshotID = landData.snapshotID; 192 updatePacket.ParcelData.ParcelFlags = landData.landFlags;
193 updatePacket.ParcelData.Status = (byte) landData.landStatus; 193 updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor;
194 updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims + 194 updatePacket.ParcelData.PassHours = landData.passHours;
195 landData.selectedPrims; 195 updatePacket.ParcelData.PassPrice = landData.passPrice;
196 updatePacket.ParcelData.UserLocation = landData.userLocation; 196 updatePacket.ParcelData.PublicCount = 0; //unemplemented
197 updatePacket.ParcelData.UserLookAt = landData.userLookAt; 197
198 remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task); 198 uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags;
199 } 199 updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) >
200 200 0);
201 public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) 201 updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) >
202 { 202 0);
203 if (remote_client.AgentId == landData.ownerID) 203 updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) >
204 { 204 0);
205 //Needs later group support 205 updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) >
206 LandData newData = landData.Copy(); 206 0);
207 newData.authBuyerID = packet.ParcelData.AuthBuyerID; 207
208 newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category; 208 updatePacket.ParcelData.RentPrice = 0;
209 newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc); 209 updatePacket.ParcelData.RequestResult = request_result;
210 newData.groupID = packet.ParcelData.GroupID; 210 updatePacket.ParcelData.SalePrice = landData.salePrice;
211 newData.landingType = packet.ParcelData.LandingType; 211 updatePacket.ParcelData.SelectedPrims = landData.selectedPrims;
212 newData.mediaAutoScale = packet.ParcelData.MediaAutoScale; 212 updatePacket.ParcelData.SelfCount = 0; //unemplemented
213 newData.mediaID = packet.ParcelData.MediaID; 213 updatePacket.ParcelData.SequenceID = sequence_id;
214 newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL); 214 if (landData.simwideArea > 0)
215 newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL); 215 {
216 newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name); 216 updatePacket.ParcelData.SimWideMaxPrims =
217 newData.landFlags = packet.ParcelData.ParcelFlags; 217 Convert.ToInt32(
218 newData.passHours = packet.ParcelData.PassHours; 218 Math.Round((Convert.ToDecimal(landData.simwideArea)/Convert.ToDecimal(65536))*15000*
219 newData.passPrice = packet.ParcelData.PassPrice; 219 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
220 newData.salePrice = packet.ParcelData.SalePrice; 220 }
221 newData.snapshotID = packet.ParcelData.SnapshotID; 221 else
222 newData.userLocation = packet.ParcelData.UserLocation; 222 {
223 newData.userLookAt = packet.ParcelData.UserLookAt; 223 updatePacket.ParcelData.SimWideMaxPrims = 0;
224 224 }
225 m_scene.LandManager.updateLandObject(landData.localID, newData); 225 updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims;
226 226 updatePacket.ParcelData.SnapSelection = snap_selection;
227 sendLandUpdateToAvatarsOverMe(); 227 updatePacket.ParcelData.SnapshotID = landData.snapshotID;
228 } 228 updatePacket.ParcelData.Status = (byte) landData.landStatus;
229 } 229 updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims +
230 230 landData.selectedPrims;
231 public bool isEitherBannedOrRestricted(LLUUID avatar) 231 updatePacket.ParcelData.UserLocation = landData.userLocation;
232 { 232 updatePacket.ParcelData.UserLookAt = landData.userLookAt;
233 if (isBannedFromLand(avatar)) 233 remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task);
234 { 234 }
235 return true; 235
236 } 236 public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
237 else if (isRestrictedFromLand(avatar)) 237 {
238 { 238 if (remote_client.AgentId == landData.ownerID)
239 return true; 239 {
240 } 240 //Needs later group support
241 return false; 241 LandData newData = landData.Copy();
242 } 242 newData.authBuyerID = packet.ParcelData.AuthBuyerID;
243 243 newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category;
244 public bool isBannedFromLand(LLUUID avatar) 244 newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc);
245 { 245 newData.groupID = packet.ParcelData.GroupID;
246 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0) 246 newData.landingType = packet.ParcelData.LandingType;
247 { 247 newData.mediaAutoScale = packet.ParcelData.MediaAutoScale;
248 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 248 newData.mediaID = packet.ParcelData.MediaID;
249 entry.AgentID = avatar; 249 newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL);
250 entry.Flags = ParcelManager.AccessList.Ban; 250 newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL);
251 entry.Time = new DateTime(); 251 newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name);
252 if (landData.parcelAccessList.Contains(entry)) 252 newData.landFlags = packet.ParcelData.ParcelFlags;
253 { 253 newData.passHours = packet.ParcelData.PassHours;
254 //They are banned, so lets send them a notice about this parcel 254 newData.passPrice = packet.ParcelData.PassPrice;
255 return true; 255 newData.salePrice = packet.ParcelData.SalePrice;
256 } 256 newData.snapshotID = packet.ParcelData.SnapshotID;
257 } 257 newData.userLocation = packet.ParcelData.UserLocation;
258 return false; 258 newData.userLookAt = packet.ParcelData.UserLookAt;
259 } 259
260 260 m_scene.LandChannel.updateLandObject(landData.localID, newData);
261 public bool isRestrictedFromLand(LLUUID avatar) 261
262 { 262 sendLandUpdateToAvatarsOverMe();
263 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0) 263 }
264 { 264 }
265 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 265
266 entry.AgentID = avatar; 266 public bool isEitherBannedOrRestricted(LLUUID avatar)
267 entry.Flags = ParcelManager.AccessList.Access; 267 {
268 entry.Time = new DateTime(); 268 if (isBannedFromLand(avatar))
269 if (!landData.parcelAccessList.Contains(entry)) 269 {
270 { 270 return true;
271 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel 271 }
272 return true; 272 else if (isRestrictedFromLand(avatar))
273 } 273 {
274 } 274 return true;
275 return false; 275 }
276 } 276 return false;
277 277 }
278 public void sendLandUpdateToClient(IClientAPI remote_client) 278
279 { 279 public bool isBannedFromLand(LLUUID avatar)
280 sendLandProperties(0, false, 0, remote_client); 280 {
281 } 281 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0)
282 282 {
283 public void sendLandUpdateToAvatarsOverMe() 283 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
284 { 284 entry.AgentID = avatar;
285 List<ScenePresence> avatars = m_scene.GetAvatars(); 285 entry.Flags = ParcelManager.AccessList.Ban;
286 Land over = null; 286 entry.Time = new DateTime();
287 for (int i = 0; i < avatars.Count; i++) 287 if (landData.parcelAccessList.Contains(entry))
288 { 288 {
289 try 289 //They are banned, so lets send them a notice about this parcel
290 { 290 return true;
291 over = 291 }
292 m_scene.LandManager.getLandObject((int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.X))), 292 }
293 (int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.Y)))); 293 return false;
294 } 294 }
295 catch (Exception) 295
296 { 296 public bool isRestrictedFromLand(LLUUID avatar)
297 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + Math.Round(avatars[i].AbsolutePosition.Y)); 297 {
298 } 298 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0)
299 299 {
300 if (over != null) 300 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
301 { 301 entry.AgentID = avatar;
302 if (over.landData.localID == landData.localID) 302 entry.Flags = ParcelManager.AccessList.Access;
303 { 303 entry.Time = new DateTime();
304 sendLandUpdateToClient(avatars[i].ControllingClient); 304 if (!landData.parcelAccessList.Contains(entry))
305 } 305 {
306 } 306 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
307 } 307 return true;
308 } 308 }
309 309 }
310 #endregion 310 return false;
311 311 }
312 #region AccessList Functions 312
313 313 public void sendLandUpdateToClient(IClientAPI remote_client)
314 public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag) 314 {
315 { 315 sendLandProperties(0, false, 0, remote_client);
316 List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>(); 316 }
317 foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList) 317
318 { 318 public void sendLandUpdateToAvatarsOverMe()
319 if (entry.Flags == flag) 319 {
320 { 320 List<ScenePresence> avatars = m_scene.GetAvatars();
321 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); 321 ILandObject over = null;
322 322 for (int i = 0; i < avatars.Count; i++)
323 listBlock.Flags = (uint) 0; 323 {
324 listBlock.ID = entry.AgentID; 324 try
325 listBlock.Time = 0; 325 {
326 326 over =
327 list.Add(listBlock); 327 m_scene.LandChannel.getLandObject((int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.X))),
328 } 328 (int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.Y))));
329 } 329 }
330 330 catch (Exception)
331 if (list.Count == 0) 331 {
332 { 332 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + Math.Round(avatars[i].AbsolutePosition.Y));
333 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); 333 }
334 334
335 listBlock.Flags = (uint) 0; 335 if (over != null)
336 listBlock.ID = LLUUID.Zero; 336 {
337 listBlock.Time = 0; 337 if (over.landData.localID == landData.localID)
338 338 {
339 list.Add(listBlock); 339 sendLandUpdateToClient(avatars[i].ControllingClient);
340 } 340 }
341 return list.ToArray(); 341 }
342 } 342 }
343 343 }
344 public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, 344
345 IClientAPI remote_client) 345 #endregion
346 { 346
347 ParcelAccessListReplyPacket replyPacket; 347 #region AccessList Functions
348 348
349 if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both) 349 public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag)
350 { 350 {
351 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); 351 List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>();
352 replyPacket.Data.AgentID = agentID; 352 foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList)
353 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access; 353 {
354 replyPacket.Data.LocalID = landData.localID; 354 if (entry.Flags == flag)
355 replyPacket.Data.SequenceID = 0; 355 {
356 356 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
357 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access); 357
358 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); 358 listBlock.Flags = (uint) 0;
359 } 359 listBlock.ID = entry.AgentID;
360 360 listBlock.Time = 0;
361 if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both) 361
362 { 362 list.Add(listBlock);
363 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); 363 }
364 replyPacket.Data.AgentID = agentID; 364 }
365 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban; 365
366 replyPacket.Data.LocalID = landData.localID; 366 if (list.Count == 0)
367 replyPacket.Data.SequenceID = 0; 367 {
368 368 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
369 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban); 369
370 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); 370 listBlock.Flags = (uint) 0;
371 } 371 listBlock.ID = LLUUID.Zero;
372 } 372 listBlock.Time = 0;
373 373
374 public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client) 374 list.Add(listBlock);
375 { 375 }
376 LandData newData = landData.Copy(); 376 return list.ToArray();
377 377 }
378 if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero) 378
379 { 379 public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID,
380 entries.Clear(); 380 IClientAPI remote_client)
381 } 381 {
382 382 ParcelAccessListReplyPacket replyPacket;
383 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>(); 383
384 foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList) 384 if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both)
385 { 385 {
386 if (entry.Flags == (ParcelManager.AccessList) flags) 386 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
387 { 387 replyPacket.Data.AgentID = agentID;
388 toRemove.Add(entry); 388 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access;
389 } 389 replyPacket.Data.LocalID = landData.localID;
390 } 390 replyPacket.Data.SequenceID = 0;
391 391
392 foreach (ParcelManager.ParcelAccessEntry entry in toRemove) 392 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access);
393 { 393 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
394 newData.parcelAccessList.Remove(entry); 394 }
395 } 395
396 foreach (ParcelManager.ParcelAccessEntry entry in entries) 396 if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both)
397 { 397 {
398 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); 398 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
399 temp.AgentID = entry.AgentID; 399 replyPacket.Data.AgentID = agentID;
400 temp.Time = new DateTime(); //Pointless? Yes. 400 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban;
401 temp.Flags = (ParcelManager.AccessList) flags; 401 replyPacket.Data.LocalID = landData.localID;
402 402 replyPacket.Data.SequenceID = 0;
403 if (!newData.parcelAccessList.Contains(temp)) 403
404 { 404 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban);
405 newData.parcelAccessList.Add(temp); 405 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
406 } 406 }
407 } 407 }
408 408
409 m_scene.LandManager.updateLandObject(landData.localID, newData); 409 public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client)
410 } 410 {
411 411 LandData newData = landData.Copy();
412 #endregion 412
413 413 if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero)
414 #region Update Functions 414 {
415 415 entries.Clear();
416 /// <summary> 416 }
417 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object 417
418 /// </summary> 418 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>();
419 private void updateAABBAndAreaValues() 419 foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList)
420 { 420 {
421 int min_x = 64; 421 if (entry.Flags == (ParcelManager.AccessList) flags)
422 int min_y = 64; 422 {
423 int max_x = 0; 423 toRemove.Add(entry);
424 int max_y = 0; 424 }
425 int tempArea = 0; 425 }
426 int x, y; 426
427 for (x = 0; x < 64; x++) 427 foreach (ParcelManager.ParcelAccessEntry entry in toRemove)
428 { 428 {
429 for (y = 0; y < 64; y++) 429 newData.parcelAccessList.Remove(entry);
430 { 430 }
431 if (landBitmap[x, y] == true) 431 foreach (ParcelManager.ParcelAccessEntry entry in entries)
432 { 432 {
433 if (min_x > x) min_x = x; 433 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry();
434 if (min_y > y) min_y = y; 434 temp.AgentID = entry.AgentID;
435 if (max_x < x) max_x = x; 435 temp.Time = new DateTime(); //Pointless? Yes.
436 if (max_y < y) max_y = y; 436 temp.Flags = (ParcelManager.AccessList) flags;
437 tempArea += 16; //16sqm peice of land 437
438 } 438 if (!newData.parcelAccessList.Contains(temp))
439 } 439 {
440 } 440 newData.parcelAccessList.Add(temp);
441 int tx = min_x * 4; 441 }
442 if (tx > 255) 442 }
443 tx = 255; 443
444 int ty = min_y * 4; 444 m_scene.LandChannel.updateLandObject(landData.localID, newData);
445 if (ty > 255) 445 }
446 ty = 255; 446
447 landData.AABBMin = 447 #endregion
448 new LLVector3((float)(min_x * 4), (float)(min_y * 4), 448
449 (float)m_scene.Heightmap[tx, ty]); 449 #region Update Functions
450 450
451 tx = max_x * 4; 451 /// <summary>
452 if (tx > 255) 452 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object
453 tx = 255; 453 /// </summary>
454 ty = max_y * 4; 454 private void updateAABBAndAreaValues()
455 if (ty > 255) 455 {
456 ty = 255; 456 int min_x = 64;
457 landData.AABBMax = 457 int min_y = 64;
458 new LLVector3((float)(max_x * 4), (float)(max_y * 4), 458 int max_x = 0;
459 (float)m_scene.Heightmap[tx, ty]); 459 int max_y = 0;
460 landData.area = tempArea; 460 int tempArea = 0;
461 } 461 int x, y;
462 462 for (x = 0; x < 64; x++)
463 public void updateLandBitmapByteArray() 463 {
464 { 464 for (y = 0; y < 64; y++)
465 landData.landBitmapByteArray = convertLandBitmapToBytes(); 465 {
466 } 466 if (landBitmap[x, y] == true)
467 467 {
468 /// <summary> 468 if (min_x > x) min_x = x;
469 /// Update all settings in land such as area, bitmap byte array, etc 469 if (min_y > y) min_y = y;
470 /// </summary> 470 if (max_x < x) max_x = x;
471 public void forceUpdateLandInfo() 471 if (max_y < y) max_y = y;
472 { 472 tempArea += 16; //16sqm peice of land
473 updateAABBAndAreaValues(); 473 }
474 updateLandBitmapByteArray(); 474 }
475 } 475 }
476 476 int tx = min_x * 4;
477 public void setLandBitmapFromByteArray() 477 if (tx > 255)
478 { 478 tx = 255;
479 landBitmap = convertBytesToLandBitmap(); 479 int ty = min_y * 4;
480 } 480 if (ty > 255)
481 481 ty = 255;
482 #endregion 482 landData.AABBMin =
483 483 new LLVector3((float)(min_x * 4), (float)(min_y * 4),
484 #region Land Bitmap Functions 484 (float)m_scene.Heightmap[tx, ty]);
485 485
486 /// <summary> 486 tx = max_x * 4;
487 /// Sets the land's bitmap manually 487 if (tx > 255)
488 /// </summary> 488 tx = 255;
489 /// <param name="bitmap">64x64 block representing where this land is on a map</param> 489 ty = max_y * 4;
490 public void setLandBitmap(bool[,] bitmap) 490 if (ty > 255)
491 { 491 ty = 255;
492 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) 492 landData.AABBMax =
493 { 493 new LLVector3((float)(max_x * 4), (float)(max_y * 4),
494 //Throw an exception - The bitmap is not 64x64 494 (float)m_scene.Heightmap[tx, ty]);
495 //throw new Exception("Error: Invalid Parcel Bitmap"); 495 landData.area = tempArea;
496 } 496 }
497 else 497
498 { 498 public void updateLandBitmapByteArray()
499 //Valid: Lets set it 499 {
500 landBitmap = bitmap; 500 landData.landBitmapByteArray = convertLandBitmapToBytes();
501 forceUpdateLandInfo(); 501 }
502 } 502
503 } 503 /// <summary>
504 504 /// Update all settings in land such as area, bitmap byte array, etc
505 /// <summary> 505 /// </summary>
506 /// Gets the land's bitmap manually 506 public void forceUpdateLandInfo()
507 /// </summary> 507 {
508 /// <returns></returns> 508 updateAABBAndAreaValues();
509 public bool[,] getLandBitmap() 509 updateLandBitmapByteArray();
510 { 510 }
511 return landBitmap; 511
512 } 512 public void setLandBitmapFromByteArray()
513 513 {
514 /// <summary> 514 landBitmap = convertBytesToLandBitmap();
515 /// Converts the land bitmap to a packet friendly byte array 515 }
516 /// </summary> 516
517 /// <returns></returns> 517 #endregion
518 private byte[] convertLandBitmapToBytes() 518
519 { 519 #region Land Bitmap Functions
520 byte[] tempConvertArr = new byte[512]; 520
521 byte tempByte = 0; 521 /// <summary>
522 int x, y, i, byteNum = 0; 522 /// Sets the land's bitmap manually
523 i = 0; 523 /// </summary>
524 for (y = 0; y < 64; y++) 524 /// <param name="bitmap">64x64 block representing where this land is on a map</param>
525 { 525 public void setLandBitmap(bool[,] bitmap)
526 for (x = 0; x < 64; x++) 526 {
527 { 527 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
528 tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++%8)); 528 {
529 if (i%8 == 0) 529 //Throw an exception - The bitmap is not 64x64
530 { 530 //throw new Exception("Error: Invalid Parcel Bitmap");
531 tempConvertArr[byteNum] = tempByte; 531 }
532 tempByte = (byte) 0; 532 else
533 i = 0; 533 {
534 byteNum++; 534 //Valid: Lets set it
535 } 535 landBitmap = bitmap;
536 } 536 forceUpdateLandInfo();
537 } 537 }
538 return tempConvertArr; 538 }
539 } 539
540 540 /// <summary>
541 private bool[,] convertBytesToLandBitmap() 541 /// Gets the land's bitmap manually
542 { 542 /// </summary>
543 bool[,] tempConvertMap = new bool[64,64]; 543 /// <returns></returns>
544 tempConvertMap.Initialize(); 544 public bool[,] getLandBitmap()
545 byte tempByte = 0; 545 {
546 int x = 0, y = 0, i = 0, bitNum = 0; 546 return landBitmap;
547 for (i = 0; i < 512; i++) 547 }
548 { 548
549 tempByte = landData.landBitmapByteArray[i]; 549 /// <summary>
550 for (bitNum = 0; bitNum < 8; bitNum++) 550 /// Converts the land bitmap to a packet friendly byte array
551 { 551 /// </summary>
552 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); 552 /// <returns></returns>
553 tempConvertMap[x, y] = bit; 553 private byte[] convertLandBitmapToBytes()
554 x++; 554 {
555 if (x > 63) 555 byte[] tempConvertArr = new byte[512];
556 { 556 byte tempByte = 0;
557 x = 0; 557 int x, y, i, byteNum = 0;
558 y++; 558 i = 0;
559 } 559 for (y = 0; y < 64; y++)
560 } 560 {
561 } 561 for (x = 0; x < 64; x++)
562 return tempConvertMap; 562 {
563 } 563 tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++%8));
564 564 if (i%8 == 0)
565 /// <summary> 565 {
566 /// Full sim land object creation 566 tempConvertArr[byteNum] = tempByte;
567 /// </summary> 567 tempByte = (byte) 0;
568 /// <returns></returns> 568 i = 0;
569 public static bool[,] basicFullRegionLandBitmap() 569 byteNum++;
570 { 570 }
571 return getSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize); 571 }
572 } 572 }
573 573 return tempConvertArr;
574 /// <summary> 574 }
575 /// Used to modify the bitmap between the x and y points. Points use 64 scale 575
576 /// </summary> 576 private bool[,] convertBytesToLandBitmap()
577 /// <param name="start_x"></param> 577 {
578 /// <param name="start_y"></param> 578 bool[,] tempConvertMap = new bool[64,64];
579 /// <param name="end_x"></param> 579 tempConvertMap.Initialize();
580 /// <param name="end_y"></param> 580 byte tempByte = 0;
581 /// <returns></returns> 581 int x = 0, y = 0, i = 0, bitNum = 0;
582 public static bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) 582 for (i = 0; i < 512; i++)
583 { 583 {
584 bool[,] tempBitmap = new bool[64,64]; 584 tempByte = landData.landBitmapByteArray[i];
585 tempBitmap.Initialize(); 585 for (bitNum = 0; bitNum < 8; bitNum++)
586 586 {
587 tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); 587 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
588 return tempBitmap; 588 tempConvertMap[x, y] = bit;
589 } 589 x++;
590 590 if (x > 63)
591 /// <summary> 591 {
592 /// Change a land bitmap at within a square and set those points to a specific value 592 x = 0;
593 /// </summary> 593 y++;
594 /// <param name="land_bitmap"></param> 594 }
595 /// <param name="start_x"></param> 595 }
596 /// <param name="start_y"></param> 596 }
597 /// <param name="end_x"></param> 597 return tempConvertMap;
598 /// <param name="end_y"></param> 598 }
599 /// <param name="set_value"></param> 599
600 /// <returns></returns> 600 /// <summary>
601 public static bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, 601 /// Full sim land object creation
602 bool set_value) 602 /// </summary>
603 { 603 /// <returns></returns>
604 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) 604 public bool[,] basicFullRegionLandBitmap()
605 { 605 {
606 //Throw an exception - The bitmap is not 64x64 606 return getSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize);
607 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); 607 }
608 } 608
609 609 /// <summary>
610 int x, y; 610 /// Used to modify the bitmap between the x and y points. Points use 64 scale
611 for (y = 0; y < 64; y++) 611 /// </summary>
612 { 612 /// <param name="start_x"></param>
613 for (x = 0; x < 64; x++) 613 /// <param name="start_y"></param>
614 { 614 /// <param name="end_x"></param>
615 if (x >= start_x/4 && x < end_x/4 615 /// <param name="end_y"></param>
616 && y >= start_y/4 && y < end_y/4) 616 /// <returns></returns>
617 { 617 public bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
618 land_bitmap[x, y] = set_value; 618 {
619 } 619 bool[,] tempBitmap = new bool[64,64];
620 } 620 tempBitmap.Initialize();
621 } 621
622 return land_bitmap; 622 tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
623 } 623 return tempBitmap;
624 624 }
625 /// <summary> 625
626 /// Join the true values of 2 bitmaps together 626 /// <summary>
627 /// </summary> 627 /// Change a land bitmap at within a square and set those points to a specific value
628 /// <param name="bitmap_base"></param> 628 /// </summary>
629 /// <param name="bitmap_add"></param> 629 /// <param name="land_bitmap"></param>
630 /// <returns></returns> 630 /// <param name="start_x"></param>
631 public static bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) 631 /// <param name="start_y"></param>
632 { 632 /// <param name="end_x"></param>
633 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) 633 /// <param name="end_y"></param>
634 { 634 /// <param name="set_value"></param>
635 //Throw an exception - The bitmap is not 64x64 635 /// <returns></returns>
636 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); 636 public bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
637 } 637 bool set_value)
638 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) 638 {
639 { 639 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
640 //Throw an exception - The bitmap is not 64x64 640 {
641 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); 641 //Throw an exception - The bitmap is not 64x64
642 } 642 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
643 643 }
644 int x, y; 644
645 for (y = 0; y < 64; y++) 645 int x, y;
646 { 646 for (y = 0; y < 64; y++)
647 for (x = 0; x < 64; x++) 647 {
648 { 648 for (x = 0; x < 64; x++)
649 if (bitmap_add[x, y]) 649 {
650 { 650 if (x >= start_x/4 && x < end_x/4
651 bitmap_base[x, y] = true; 651 && y >= start_y/4 && y < end_y/4)
652 } 652 {
653 } 653 land_bitmap[x, y] = set_value;
654 } 654 }
655 return bitmap_base; 655 }
656 } 656 }
657 657 return land_bitmap;
658 #endregion 658 }
659 659
660 #region Object Select and Object Owner Listing 660 /// <summary>
661 661 /// Join the true values of 2 bitmaps together
662 public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client) 662 /// </summary>
663 { 663 /// <param name="bitmap_base"></param>
664 List<uint> resultLocalIDs = new List<uint>(); 664 /// <param name="bitmap_add"></param>
665 foreach (SceneObjectGroup obj in primsOverMe) 665 /// <returns></returns>
666 { 666 public bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
667 if (obj.LocalId > 0) 667 {
668 { 668 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
669 if (request_type == LandManager.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID) 669 {
670 { 670 //Throw an exception - The bitmap is not 64x64
671 resultLocalIDs.Add(obj.LocalId); 671 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
672 } 672 }
673 // else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support 673 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
674 // { 674 {
675 // } 675 //Throw an exception - The bitmap is not 64x64
676 else if (request_type == LandManager.LAND_SELECT_OBJECTS_OTHER && 676 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
677 obj.OwnerID != remote_client.AgentId) 677 }
678 { 678
679 resultLocalIDs.Add(obj.LocalId); 679 int x, y;
680 } 680 for (y = 0; y < 64; y++)
681 } 681 {
682 } 682 for (x = 0; x < 64; x++)
683 683 {
684 684 if (bitmap_add[x, y])
685 bool firstCall = true; 685 {
686 int MAX_OBJECTS_PER_PACKET = 251; 686 bitmap_base[x, y] = true;
687 ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); 687 }
688 // TODO: don't create new blocks if recycling an old packet 688 }
689 ForceObjectSelectPacket.DataBlock[] data; 689 }
690 while (resultLocalIDs.Count > 0) 690 return bitmap_base;
691 { 691 }
692 if (firstCall) 692
693 { 693 #endregion
694 pack._Header.ResetList = true; 694
695 firstCall = false; 695 #region Object Select and Object Owner Listing
696 } 696
697 else 697 public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client)
698 { 698 {
699 pack._Header.ResetList = false; 699 List<uint> resultLocalIDs = new List<uint>();
700 } 700 foreach (SceneObjectGroup obj in primsOverMe)
701 701 {
702 if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET) 702 if (obj.LocalId > 0)
703 { 703 {
704 data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET]; 704 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID)
705 } 705 {
706 else 706 resultLocalIDs.Add(obj.LocalId);
707 { 707 }
708 data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count]; 708 // else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support
709 } 709 // {
710 710 // }
711 int i; 711 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER &&
712 for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++) 712 obj.OwnerID != remote_client.AgentId)
713 { 713 {
714 data[i] = new ForceObjectSelectPacket.DataBlock(); 714 resultLocalIDs.Add(obj.LocalId);
715 data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]); 715 }
716 resultLocalIDs.RemoveAt(0); 716 }
717 } 717 }
718 pack.Data = data; 718
719 remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task); 719
720 } 720 bool firstCall = true;
721 } 721 int MAX_OBJECTS_PER_PACKET = 251;
722 722 ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect);
723 public void sendLandObjectOwners(IClientAPI remote_client) 723 // TODO: don't create new blocks if recycling an old packet
724 { 724 ForceObjectSelectPacket.DataBlock[] data;
725 Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>(); 725 while (resultLocalIDs.Count > 0)
726 ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); 726 {
727 // TODO: don't create new blocks if recycling an old packet 727 if (firstCall)
728 728 {
729 foreach (SceneObjectGroup obj in primsOverMe) 729 pack._Header.ResetList = true;
730 { 730 firstCall = false;
731 if (!ownersAndCount.ContainsKey(obj.OwnerID)) 731 }
732 { 732 else
733 ownersAndCount.Add(obj.OwnerID, 0); 733 {
734 } 734 pack._Header.ResetList = false;
735 ownersAndCount[obj.OwnerID] += obj.PrimCount; 735 }
736 } 736
737 if (ownersAndCount.Count > 0) 737 if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET)
738 { 738 {
739 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[32]; 739 data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET];
740 740 }
741 if (ownersAndCount.Count < 32) 741 else
742 { 742 {
743 dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[ownersAndCount.Count]; 743 data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count];
744 } 744 }
745 745
746 746 int i;
747 int num = 0; 747 for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++)
748 foreach (LLUUID owner in ownersAndCount.Keys) 748 {
749 { 749 data[i] = new ForceObjectSelectPacket.DataBlock();
750 dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock(); 750 data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]);
751 dataBlock[num].Count = ownersAndCount[owner]; 751 resultLocalIDs.RemoveAt(0);
752 dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added 752 }
753 dataBlock[num].OnlineStatus = true; //TODO: fix me later 753 pack.Data = data;
754 dataBlock[num].OwnerID = owner; 754 remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task);
755 755 }
756 num++; 756 }
757 } 757
758 pack.Data = dataBlock; 758 public void sendLandObjectOwners(IClientAPI remote_client)
759 } 759 {
760 remote_client.OutPacket(pack, ThrottleOutPacketType.Task); 760 Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>();
761 } 761 ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
762 762 // TODO: don't create new blocks if recycling an old packet
763 #endregion 763
764 764 foreach (SceneObjectGroup obj in primsOverMe)
765 #region Object Returning 765 {
766 766 if (!ownersAndCount.ContainsKey(obj.OwnerID))
767 public void returnObject(SceneObjectGroup obj) 767 {
768 { 768 ownersAndCount.Add(obj.OwnerID, 0);
769 } 769 }
770 770 ownersAndCount[obj.OwnerID] += obj.PrimCount;
771 public void returnLandObjects(int type, LLUUID owner) 771 }
772 { 772 if (ownersAndCount.Count > 0)
773 } 773 {
774 774 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[32];
775 #endregion 775
776 776 if (ownersAndCount.Count < 32)
777 #region Object Adding/Removing from Parcel 777 {
778 778 dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[ownersAndCount.Count];
779 public void resetLandPrimCounts() 779 }
780 { 780
781 landData.groupPrims = 0; 781
782 landData.ownerPrims = 0; 782 int num = 0;
783 landData.otherPrims = 0; 783 foreach (LLUUID owner in ownersAndCount.Keys)
784 landData.selectedPrims = 0; 784 {
785 primsOverMe.Clear(); 785 dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock();
786 } 786 dataBlock[num].Count = ownersAndCount[owner];
787 787 dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added
788 public void addPrimToCount(SceneObjectGroup obj) 788 dataBlock[num].OnlineStatus = true; //TODO: fix me later
789 { 789 dataBlock[num].OwnerID = owner;
790 LLUUID prim_owner = obj.OwnerID; 790
791 int prim_count = obj.PrimCount; 791 num++;
792 792 }
793 if (obj.IsSelected) 793 pack.Data = dataBlock;
794 { 794 }
795 landData.selectedPrims += prim_count; 795 remote_client.OutPacket(pack, ThrottleOutPacketType.Task);
796 } 796 }
797 else 797
798 { 798 #endregion
799 if (prim_owner == landData.ownerID) 799
800 { 800 #region Object Returning
801 landData.ownerPrims += prim_count; 801
802 } 802 public void returnObject(SceneObjectGroup obj)
803 else 803 {
804 { 804 }
805 landData.otherPrims += prim_count; 805
806 } 806 public void returnLandObjects(int type, LLUUID owner)
807 } 807 {
808 808 }
809 primsOverMe.Add(obj); 809
810 } 810 #endregion
811 811
812 public void removePrimFromCount(SceneObjectGroup obj) 812 #region Object Adding/Removing from Parcel
813 { 813
814 if (primsOverMe.Contains(obj)) 814 public void resetLandPrimCounts()
815 { 815 {
816 LLUUID prim_owner = obj.OwnerID; 816 landData.groupPrims = 0;
817 int prim_count = obj.PrimCount; 817 landData.ownerPrims = 0;
818 818 landData.otherPrims = 0;
819 if (prim_owner == landData.ownerID) 819 landData.selectedPrims = 0;
820 { 820 primsOverMe.Clear();
821 landData.ownerPrims -= prim_count; 821 }
822 } 822
823 else if (prim_owner == landData.groupID) 823 public void addPrimToCount(SceneObjectGroup obj)
824 { 824 {
825 landData.groupPrims -= prim_count; 825 LLUUID prim_owner = obj.OwnerID;
826 } 826 int prim_count = obj.PrimCount;
827 else 827
828 { 828 if (obj.IsSelected)
829 landData.otherPrims -= prim_count; 829 {
830 } 830 landData.selectedPrims += prim_count;
831 831 }
832 primsOverMe.Remove(obj); 832 else
833 } 833 {
834 } 834 if (prim_owner == landData.ownerID)
835 835 {
836 #endregion 836 landData.ownerPrims += prim_count;
837 837 }
838 #endregion 838 else
839 } 839 {
840 840 landData.otherPrims += prim_count;
841 #endregion 841 }
842} 842 }
843
844 primsOverMe.Add(obj);
845 }
846
847 public void removePrimFromCount(SceneObjectGroup obj)
848 {
849 if (primsOverMe.Contains(obj))
850 {
851 LLUUID prim_owner = obj.OwnerID;
852 int prim_count = obj.PrimCount;
853
854 if (prim_owner == landData.ownerID)
855 {
856 landData.ownerPrims -= prim_count;
857 }
858 else if (prim_owner == landData.groupID)
859 {
860 landData.groupPrims -= prim_count;
861 }
862 else
863 {
864 landData.otherPrims -= prim_count;
865 }
866
867 primsOverMe.Remove(obj);
868 }
869 }
870
871 #endregion
872
873 #endregion
874
875
876}
877
878 #endregion
879}