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