From 5e4d6cab00cb29cd088ab7b62ab13aff103b64cb Mon Sep 17 00:00:00 2001
From: onefang
Date: Sun, 19 May 2019 21:24:15 +1000
Subject: Dump OpenSim 0.9.0.1 into it's own branch.
---
.../CoreModules/World/Land/LandManagementModule.cs | 1333 ++++++++++++--------
1 file changed, 793 insertions(+), 540 deletions(-)
(limited to 'OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs')
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;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
+using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@@ -52,7 +53,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.World.Land
{
// used for caching
- internal class ExtendedLandData
+ internal class ExtendedLandData
{
public LandData LandData;
public ulong RegionHandle;
@@ -69,9 +70,8 @@ namespace OpenSim.Region.CoreModules.World.Land
///
/// Minimum land unit size in region co-ordinates.
///
- public const int LandUnit = 4;
- private static readonly string remoteParcelRequestPath = "0009/";
+ public const int LandUnit = 4;
private LandChannel landChannel;
private Scene m_scene;
@@ -89,20 +89,27 @@ namespace OpenSim.Region.CoreModules.World.Land
///
/// Land objects keyed by local id
///
- private readonly Dictionary m_landList = new Dictionary();
+// private readonly Dictionary m_landList = new Dictionary();
+
+ //ubit: removed the readonly so i can move it around
+ private Dictionary m_landList = new Dictionary();
+ private Dictionary m_landUUIDList = new Dictionary();
private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
private bool m_allowedForcefulBans = true;
+ private bool m_showBansLines = true;
+ private UUID DefaultGodParcelGroup;
+ private string DefaultGodParcelName;
// caches ExtendedLandData
private Cache parcelInfoCache;
-
///
/// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
///
- private Dictionary forcedPosition = new Dictionary();
+ private HashSet forcedPosition = new HashSet();
+
// Enables limiting parcel layer info transmission when doing simple updates
private bool shouldLimitParcelLayerInfoToViewDistance { get; set; }
@@ -125,6 +132,11 @@ namespace OpenSim.Region.CoreModules.World.Land
{
shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance);
parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance);
+ DefaultGodParcelGroup = new UUID(landManagementConfig.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
+ DefaultGodParcelName = landManagementConfig.GetString("DefaultAdministratorParcelName", "Default Parcel");
+ bool disablebans = landManagementConfig.GetBoolean("DisableParcelBans", !m_allowedForcefulBans);
+ m_allowedForcefulBans = !disablebans;
+ m_showBansLines = landManagementConfig.GetBoolean("ShowParcelBansLines", m_showBansLines);
}
}
@@ -132,17 +144,20 @@ namespace OpenSim.Region.CoreModules.World.Land
{
m_scene = scene;
m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
+
landChannel = new LandChannel(scene, this);
parcelInfoCache = new Cache();
parcelInfoCache.Size = 30; // the number of different parcel requests in this region to cache
parcelInfoCache.DefaultTTL = new TimeSpan(0, 5, 0);
+ m_scene.EventManager.OnObjectAddedToScene += EventManagerOnParcelPrimCountAdd;
m_scene.EventManager.OnParcelPrimCountAdd += EventManagerOnParcelPrimCountAdd;
+
+ m_scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene;
m_scene.EventManager.OnParcelPrimCountUpdate += EventManagerOnParcelPrimCountUpdate;
- m_scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene;
m_scene.EventManager.OnRequestParcelPrimCountUpdate += EventManagerOnRequestParcelPrimCountUpdate;
-
+
m_scene.EventManager.OnAvatarEnteringNewParcel += EventManagerOnAvatarEnteringNewParcel;
m_scene.EventManager.OnClientMovement += EventManagerOnClientMovement;
m_scene.EventManager.OnValidateLandBuy += EventManagerOnValidateLandBuy;
@@ -152,14 +167,14 @@ namespace OpenSim.Region.CoreModules.World.Land
m_scene.EventManager.OnSignificantClientMovement += EventManagerOnSignificantClientMovement;
m_scene.EventManager.OnNoticeNoLandDataFromStorage += EventManagerOnNoLandDataFromStorage;
m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage;
- m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan;
+ m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan;
m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps;
lock (m_scene)
{
m_scene.LandChannel = (ILandChannel)landChannel;
}
-
+
RegisterCommands();
}
@@ -172,8 +187,8 @@ namespace OpenSim.Region.CoreModules.World.Land
}
public void RemoveRegion(Scene scene)
- {
- // TODO: Release event manager listeners here
+ {
+ // TODO: Release event manager listeners here
}
// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
@@ -181,7 +196,7 @@ namespace OpenSim.Region.CoreModules.World.Land
// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
// reason = "You are not allowed to enter this sim.";
// return nearestParcel != null;
-// }
+// }
void EventManagerOnNewClient(IClientAPI client)
{
@@ -199,18 +214,10 @@ namespace OpenSim.Region.CoreModules.World.Land
client.OnParcelReclaim += ClientOnParcelReclaim;
client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
- client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
client.OnParcelEjectUser += ClientOnParcelEjectUser;
client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
client.OnSetStartLocationRequest += ClientOnSetHome;
-
-
- EntityBase presenceEntity;
- if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
- {
- SendLandUpdate((ScenePresence)presenceEntity, true);
- SendParcelOverlay(client);
- }
+ client.OnParcelBuyPass += ClientParcelBuyPass;
}
public void EventMakeChildAgent(ScenePresence avatar)
@@ -218,52 +225,6 @@ namespace OpenSim.Region.CoreModules.World.Land
avatar.currentParcelUUID = UUID.Zero;
}
- void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
- {
- //If we are forcing a position for them to go
- if (forcedPosition.ContainsKey(remoteClient.AgentId))
- {
- ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
-
- //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
- //When the avatar walks into a ban line on the ground, it prevents getting stuck
- agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
-
- //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
- if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
- {
-// m_log.DebugFormat(
-// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
-// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
-
- forcedPosition.Remove(remoteClient.AgentId);
- }
- //if we are far away, teleport
- else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
- {
- Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
-// m_log.DebugFormat(
-// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
-// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
-
- m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
- forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
-
- forcedPosition.Remove(remoteClient.AgentId);
- }
- else
- {
-// m_log.DebugFormat(
-// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
-// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
-
- //Forces them toward the forced position we want if they aren't there yet
- agentData.UseClientAgentPosition = true;
- agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
- }
- }
- }
-
public void Close()
{
}
@@ -291,7 +252,10 @@ namespace OpenSim.Region.CoreModules.World.Land
lock (m_landList)
{
if (m_landList.TryGetValue(local_id, out land))
+ {
land.LandData = newData;
+ m_landUUIDList[newData.GlobalID] = local_id;
+ }
}
if (land != null)
@@ -312,28 +276,35 @@ namespace OpenSim.Region.CoreModules.World.Land
//Remove all the land objects in the sim and add a blank, full sim land object set to public
lock (m_landList)
{
+ foreach(ILandObject parcel in m_landList.Values)
+ parcel.Clear();
+
m_landList.Clear();
+ m_landUUIDList.Clear();
m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
+
m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
}
}
-
+
///
/// Create a default parcel that spans the entire region and is owned by the estate owner.
///
/// The parcel created.
protected ILandObject CreateDefaultParcel()
{
- m_log.DebugFormat(
- "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
-
- ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
+ m_log.DebugFormat("{0} Creating default parcel for region {1}", LogHeader, m_scene.RegionInfo.RegionName);
+
+ ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
+
fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
(int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
- fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
- fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
-
- return AddLandObject(fullSimParcel);
+ LandData ldata = fullSimParcel.LandData;
+ ldata.SimwideArea = ldata.Area;
+ ldata.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
+ ldata.ClaimDate = Util.UnixTimeSinceEpoch();
+
+ return AddLandObject(fullSimParcel);
}
public List AllParcels()
@@ -347,9 +318,9 @@ namespace OpenSim.Region.CoreModules.World.Land
public List ParcelsNearPoint(Vector3 position)
{
List parcelsNear = new List();
- for (int x = -4; x <= 4; x += 4)
+ for (int x = -8; x <= 8; x += 4)
{
- for (int y = -4; y <= 4; y += 4)
+ for (int y = -8; y <= 8; y += 4)
{
ILandObject check = GetLandObject(position.X + x, position.Y + y);
if (check != null)
@@ -365,33 +336,99 @@ namespace OpenSim.Region.CoreModules.World.Land
return parcelsNear;
}
- public void SendYouAreBannedNotice(ScenePresence avatar)
+ // checks and enforces bans or restrictions
+ // returns true if enforced
+ public bool EnforceBans(ILandObject land, ScenePresence avatar)
{
- if (AllowedForcefulBans)
+ Vector3 agentpos = avatar.AbsolutePosition;
+ float h = m_scene.GetGroundHeight(agentpos.X, agentpos.Y) + LandChannel.BAN_LINE_SAFETY_HEIGHT;
+ float zdif = avatar.AbsolutePosition.Z - h;
+ if (zdif > 0 )
+ {
+ forcedPosition.Remove(avatar.UUID);
+ avatar.lastKnownAllowedPosition = agentpos;
+ return false;
+ }
+
+ bool ban = false;
+ string reason = "";
+ if (land.IsRestrictedFromLand(avatar.UUID))
{
- avatar.ControllingClient.SendAlertMessage(
- "You are not allowed on this parcel because you are banned. Please go away.");
+ reason = "You do not have access to the parcel";
+ ban = true;
+ }
+
+ if (land.IsBannedFromLand(avatar.UUID))
+ {
+ if ( m_allowedForcefulBans)
+ {
+ reason ="You are banned from parcel";
+ ban = true;
+ }
+ else if(!ban)
+ {
+ if (forcedPosition.Contains(avatar.UUID))
+ avatar.ControllingClient.SendAlertMessage("You are banned from parcel, please leave by your own will");
+ forcedPosition.Remove(avatar.UUID);
+ avatar.lastKnownAllowedPosition = agentpos;
+ return false;
+ }
+ }
+
+ if(ban)
+ {
+ if (!forcedPosition.Contains(avatar.UUID))
+ avatar.ControllingClient.SendAlertMessage(reason);
+
+ if(zdif > -4f)
+ {
+
+ agentpos.Z = h + 4.0f;
+ ForceAvatarToPosition(avatar, agentpos);
+ return true;
+ }
+
+ if (land.ContainsPoint((int)avatar.lastKnownAllowedPosition.X,
+ (int) avatar.lastKnownAllowedPosition.Y))
+ {
+ Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
+ if (pos == null)
+ {
+ forcedPosition.Remove(avatar.UUID);
+ m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
+ }
+ else
+ ForceAvatarToPosition(avatar, (Vector3)pos);
+ }
+ else
+ {
+ ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
+ }
+ return true;
}
else
{
- avatar.ControllingClient.SendAlertMessage(
- "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!");
+ forcedPosition.Remove(avatar.UUID);
+ avatar.lastKnownAllowedPosition = agentpos;
+ return false;
}
}
private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
{
if (m_scene.Permissions.IsGod(avatar.UUID)) return;
- if (position.HasValue)
- {
- forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position;
- }
- }
- public void SendYouAreRestrictedNotice(ScenePresence avatar)
- {
- avatar.ControllingClient.SendAlertMessage(
- "You are not allowed on this parcel because the land owner has restricted access.");
+ if (!position.HasValue)
+ return;
+
+ if(avatar.MovingToTarget)
+ avatar.ResetMoveToTarget();
+ avatar.AbsolutePosition = position.Value;
+ avatar.lastKnownAllowedPosition = position.Value;
+ avatar.Velocity = Vector3.Zero;
+ if(avatar.IsSatOnObject)
+ avatar.StandUp();
+ forcedPosition.Add(avatar.UUID);
}
public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
@@ -404,29 +441,12 @@ namespace OpenSim.Region.CoreModules.World.Land
parcelAvatarIsEntering = m_landList[localLandID];
}
- if (parcelAvatarIsEntering != null)
+ if (parcelAvatarIsEntering != null &&
+ avatar.currentParcelUUID != parcelAvatarIsEntering.LandData.GlobalID)
{
- if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
- {
- if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
- {
- SendYouAreBannedNotice(avatar);
- ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
- }
- else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
- {
- SendYouAreRestrictedNotice(avatar);
- ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
- }
- else
- {
- avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
- }
- }
- else
- {
- avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
- }
+ SendLandUpdate(avatar, parcelAvatarIsEntering);
+ avatar.currentParcelUUID = parcelAvatarIsEntering.LandData.GlobalID;
+ EnforceBans(parcelAvatarIsEntering, avatar);
}
}
}
@@ -434,7 +454,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void SendOutNearestBanLine(IClientAPI client)
{
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
- if (sp == null || sp.IsChildAgent)
+ if (sp == null || sp.IsDeleted)
return;
List checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition);
@@ -454,98 +474,180 @@ namespace OpenSim.Region.CoreModules.World.Land
return;
}
- public void SendLandUpdate(ScenePresence avatar, bool force)
+ public void sendClientInitialLandInfo(IClientAPI remoteClient)
{
- ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
- (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
+ ScenePresence avatar;
- if (over != null)
+ if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out avatar))
+ return;
+
+ if (!avatar.IsChildAgent)
{
- if (force)
- {
- if (!avatar.IsChildAgent)
- {
- over.SendLandUpdateToClient(avatar.ControllingClient);
- m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
- m_scene.RegionInfo.RegionID);
- }
- }
+ ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
+ if (over == null)
+ return;
- if (avatar.currentParcelUUID != over.LandData.GlobalID)
- {
- if (!avatar.IsChildAgent)
- {
- over.SendLandUpdateToClient(avatar.ControllingClient);
- avatar.currentParcelUUID = over.LandData.GlobalID;
- m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
- m_scene.RegionInfo.RegionID);
- }
- }
+ avatar.currentParcelUUID = over.LandData.GlobalID;
+ over.SendLandUpdateToClient(avatar.ControllingClient);
}
+ SendParcelOverlay(remoteClient);
}
- public void SendLandUpdate(ScenePresence avatar)
+ public void SendLandUpdate(ScenePresence avatar, ILandObject over)
{
- SendLandUpdate(avatar, false);
- }
+ if (avatar.IsChildAgent)
+ return;
- public void EventManagerOnSignificantClientMovement(ScenePresence clientAvatar)
- {
- SendLandUpdate(clientAvatar);
- SendOutNearestBanLine(clientAvatar.ControllingClient);
- ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
- if (parcel != null)
+ if (over != null)
{
- if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
- clientAvatar.sentMessageAboutRestrictedParcelFlyingDown)
- {
- EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID,
- m_scene.RegionInfo.RegionID);
- //They are going under the safety line!
- if (!parcel.IsBannedFromLand(clientAvatar.UUID))
- {
- clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
- }
- }
- else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
- parcel.IsBannedFromLand(clientAvatar.UUID))
- {
- //once we've sent the message once, keep going toward the target until we are done
- if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
- {
- SendYouAreBannedNotice(clientAvatar);
- ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
- }
- }
- else if (parcel.IsRestrictedFromLand(clientAvatar.UUID))
- {
- //once we've sent the message once, keep going toward the target until we are done
- if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
- {
- SendYouAreRestrictedNotice(clientAvatar);
- ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
- }
- }
- else
- {
- //when we are finally in a safe place, lets release the forced position lock
- forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
- }
+ over.SendLandUpdateToClient(avatar.ControllingClient);
+// sl doesnt seem to send this now, as it used 2
+// SendParcelOverlay(avatar.ControllingClient);
}
}
+ public void EventManagerOnSignificantClientMovement(ScenePresence avatar)
+ {
+ if (avatar.IsChildAgent)
+ return;
+
+ if ( m_allowedForcefulBans && m_showBansLines)
+ SendOutNearestBanLine(avatar.ControllingClient);
+ }
+
///
/// Like handleEventManagerOnSignificantClientMovement, but called with an AgentUpdate regardless of distance.
///
///
public void EventManagerOnClientMovement(ScenePresence avatar)
{
+ if (avatar.IsChildAgent)
+ return;
+
Vector3 pos = avatar.AbsolutePosition;
ILandObject over = GetLandObject(pos.X, pos.Y);
if (over != null)
{
- if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || pos.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT))
- avatar.lastKnownAllowedPosition = pos;
+ EnforceBans(over, avatar);
+ pos = avatar.AbsolutePosition;
+ ILandObject newover = GetLandObject(pos.X, pos.Y);
+ if(over != newover || avatar.currentParcelUUID != newover.LandData.GlobalID)
+ {
+ m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar,
+ newover.LandData.LocalID, m_scene.RegionInfo.RegionID);
+ }
+ }
+ }
+
+ public void ClientParcelBuyPass(IClientAPI remote_client, UUID targetID, int landLocalID)
+ {
+ ILandObject land;
+ lock (m_landList)
+ {
+ m_landList.TryGetValue(landLocalID, out land);
+ }
+ // trivial checks
+ if(land == null)
+ return;
+
+ LandData ldata = land.LandData;
+
+ if(ldata == null)
+ return;
+
+ if(ldata.OwnerID == targetID)
+ return;
+
+ if(ldata.PassHours == 0)
+ return;
+
+ // don't allow passes on group owned until we can give money to groups
+ if(ldata.IsGroupOwned)
+ {
+ remote_client.SendAgentAlertMessage("pass to group owned parcel not suported", false);
+ return;
+ }
+
+ if((ldata.Flags & (uint)ParcelFlags.UsePassList) == 0)
+ return;
+
+ int cost = ldata.PassPrice;
+
+ int idx = land.LandData.ParcelAccessList.FindIndex(
+ delegate(LandAccessEntry e)
+ {
+ if (e.AgentID == targetID && e.Flags == AccessList.Access)
+ return true;
+ return false;
+ });
+ int now = Util.UnixTimeSinceEpoch();
+ int expires = (int)(3600.0 * ldata.PassHours + 0.5f);
+ int currenttime = -1;
+ if (idx != -1)
+ {
+ if(ldata.ParcelAccessList[idx].Expires == 0)
+ {
+ remote_client.SendAgentAlertMessage("You already have access to parcel", false);
+ return;
+ }
+
+ currenttime = ldata.ParcelAccessList[idx].Expires - now;
+ if(currenttime > (int)(0.25f * expires + 0.5f))
+ {
+ if(currenttime > 3600)
+ remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.###} hours",
+ currenttime/3600f), false);
+ else if(currenttime > 60)
+ remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.##} minutes",
+ currenttime/60f), false);
+ else
+ remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.#} seconds",
+ currenttime), false);
+ return;
+ }
+ }
+
+ LandAccessEntry entry = new LandAccessEntry();
+ entry.AgentID = targetID;
+ entry.Flags = AccessList.Access;
+ entry.Expires = now + expires;
+ if(currenttime > 0)
+ entry.Expires += currenttime;
+ IMoneyModule mm = m_scene.RequestModuleInterface();
+ if(cost != 0 && mm != null)
+ {
+ WorkManager.RunInThreadPool(
+ delegate
+ {
+ string regionName = m_scene.RegionInfo.RegionName;
+
+ if (!mm.AmountCovered(remote_client.AgentId, cost))
+ {
+ remote_client.SendAgentAlertMessage(String.Format("Insufficient funds in region '{0}' money system", regionName), true);
+ return;
+ }
+
+ string payDescription = String.Format("Parcel '{0}' at region '{1} {2:0.###} hours access pass", ldata.Name, regionName, ldata.PassHours);
+
+ if(!mm.MoveMoney(remote_client.AgentId, ldata.OwnerID, cost,MoneyTransactionType.LandPassSale, payDescription))
+ {
+ remote_client.SendAgentAlertMessage("Sorry pass payment processing failed, please try again later", true);
+ return;
+ }
+
+ if (idx != -1)
+ ldata.ParcelAccessList.RemoveAt(idx);
+ ldata.ParcelAccessList.Add(entry);
+ m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
+ return;
+ }, null, "ParcelBuyPass");
+ }
+ else
+ {
+ if (idx != -1)
+ ldata.ParcelAccessList.RemoveAt(idx);
+ ldata.ParcelAccessList.Add(entry);
+ m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
}
}
@@ -589,7 +691,7 @@ namespace OpenSim.Region.CoreModules.World.Land
requiredPowers = GroupPowers.LandManageBanned;
if (m_scene.Permissions.CanEditParcelProperties(agentID,
- land, requiredPowers))
+ land, requiredPowers, false))
{
land.UpdateAccessList(flags, transactionID, sequenceID,
sections, entries, remote_client);
@@ -605,13 +707,11 @@ namespace OpenSim.Region.CoreModules.World.Land
/// Adds a land object to the stored list and adds them to the landIDList to what they own
///
///
- /// The land object being added.
+ /// The land object being added.
/// Will return null if this overlaps with an existing parcel that has not had its bitmap adjusted.
///
- public ILandObject AddLandObject(ILandObject land)
+ public ILandObject AddLandObject(ILandObject new_land)
{
- ILandObject new_land = land.Copy();
-
// Only now can we add the prim counts to the land object - we rely on the global ID which is generated
// as a random UUID inside LandData initialization
if (m_primCountModule != null)
@@ -623,18 +723,15 @@ namespace OpenSim.Region.CoreModules.World.Land
new_land.LandData.LocalID = newLandLocalID;
bool[,] landBitmap = new_land.GetLandBitmap();
- // m_log.DebugFormat("{0} AddLandObject. new_land.bitmapSize=({1},{2}). newLocalID={3}",
- // LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), newLandLocalID);
-
if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
{
// Going to variable sized regions can cause mismatches
m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})",
- LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1) );
+ LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1));
}
else
{
- // If other land objects still believe that they occupy any parts of the same space,
+ // If other land objects still believe that they occupy any parts of the same space,
// then do not allow the add to proceed.
for (int x = 0; x < landBitmap.GetLength(0); x++)
{
@@ -652,7 +749,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
m_log.ErrorFormat(
"{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}",
- LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y,
+ LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y,
lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name);
return null;
@@ -668,10 +765,10 @@ namespace OpenSim.Region.CoreModules.World.Land
{
if (landBitmap[x, y])
{
- // m_log.DebugFormat(
- // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
- // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
-
+ // m_log.DebugFormat(
+ // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
+ // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
+
m_landIDList[x, y] = newLandLocalID;
}
}
@@ -679,6 +776,7 @@ namespace OpenSim.Region.CoreModules.World.Land
}
m_landList.Add(newLandLocalID, new_land);
+ m_landUUIDList[new_land.LandData.GlobalID] = newLandLocalID;
m_lastLandLocalID++;
}
@@ -695,6 +793,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void removeLandObject(int local_id)
{
ILandObject land;
+ UUID landGlobalID = UUID.Zero;
lock (m_landList)
{
for (int x = 0; x < m_landIDList.GetLength(0); x++)
@@ -713,37 +812,47 @@ namespace OpenSim.Region.CoreModules.World.Land
land = m_landList[local_id];
m_landList.Remove(local_id);
+ if(land != null && land.LandData != null)
+ {
+ landGlobalID = land.LandData.GlobalID;
+ m_landUUIDList.Remove(landGlobalID);
+ }
}
- m_scene.EventManager.TriggerLandObjectRemoved(land.LandData.GlobalID);
+ if(landGlobalID != UUID.Zero)
+ {
+ m_scene.EventManager.TriggerLandObjectRemoved(landGlobalID);
+ land.Clear();
+ }
}
-
+
///
/// Clear the scene of all parcels
- ///
+ ///
public void Clear(bool setupDefaultParcel)
{
- List parcels;
+ Dictionary landworkList;
+ // move to work pointer since we are deleting it all
lock (m_landList)
{
- parcels = new List(m_landList.Values);
+ landworkList = m_landList;
+ m_landList = new Dictionary();
}
- foreach (ILandObject lo in parcels)
+ // this 2 methods have locks (now)
+ ResetSimLandObjects();
+
+ if (setupDefaultParcel)
+ CreateDefaultParcel();
+
+ // fire outside events unlocked
+ foreach (ILandObject lo in landworkList.Values)
{
//m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
}
+ landworkList.Clear();
- lock (m_landList)
- {
- m_landList.Clear();
-
- ResetSimLandObjects();
- }
-
- if (setupDefaultParcel)
- CreateDefaultParcel();
}
private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -762,11 +871,29 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
}
-
+ master.LandData.Dwell += slave.LandData.Dwell;
removeLandObject(slave.LandData.LocalID);
UpdateLandObject(master.LandData.LocalID, master.LandData);
}
+ public ILandObject GetLandObject(UUID globalID)
+ {
+ lock (m_landList)
+ {
+ int lid = -1;
+ if(m_landUUIDList.TryGetValue(globalID, out lid) && lid >= 0)
+ {
+ if (m_landList.ContainsKey(lid))
+ {
+ return m_landList[lid];
+ }
+ else
+ m_landUUIDList.Remove(globalID); // auto heal
+ }
+ }
+ return null;
+ }
+
public ILandObject GetLandObject(int parcelLocalID)
{
lock (m_landList)
@@ -787,58 +914,37 @@ namespace OpenSim.Region.CoreModules.World.Land
/// Land object at the point supplied
public ILandObject GetLandObject(float x_float, float y_float)
{
- return GetLandObject((int)x_float, (int)y_float, true /* returnNullIfLandObjectNotFound */);
- /*
- int x;
- int y;
-
- if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0)
- return null;
+ return GetLandObject((int)x_float, (int)y_float, true);
+ }
- try
- {
- x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit));
- y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit));
- }
- catch (OverflowException)
- {
- return null;
- }
+ // if x,y is off region this will return the parcel at cliped x,y
+ // as did code it replaces
+ public ILandObject GetLandObjectClipedXY(float x, float y)
+ {
+ //do clip inline
+ int avx = (int)x;
+ if (avx < 0)
+ avx = 0;
+ else if (avx >= m_scene.RegionInfo.RegionSizeX)
+ avx = (int)Constants.RegionSize - 1;
- if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit)
- || y >= (m_scene.RegionInfo.RegionSizeY / landUnit)
- || x < 0
- || y < 0)
- {
- return null;
- }
+ int avy = (int)y;
+ if (avy < 0)
+ avy = 0;
+ else if (avy >= m_scene.RegionInfo.RegionSizeY)
+ avy = (int)Constants.RegionSize - 1;
- lock (m_landList)
+ lock (m_landIDList)
{
- // Corner case. If an autoreturn happens during sim startup
- // we will come here with the list uninitialized
- //
-// int landId = m_landIDList[x, y];
-
-// if (landId == 0)
-// m_log.DebugFormat(
-// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
-// x, y, m_scene.RegionInfo.RegionName);
-
try
{
- if (m_landList.ContainsKey(m_landIDList[x, y]))
- return m_landList[m_landIDList[x, y]];
+ return m_landList[m_landIDList[avx / LandUnit, avy / LandUnit]];
}
- catch (Exception e)
+ catch (IndexOutOfRangeException)
{
- m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})",
- LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
+ return null;
}
-
- return null;
}
- */
}
// Public entry.
@@ -848,33 +954,32 @@ namespace OpenSim.Region.CoreModules.World.Land
return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */);
}
- ///
- /// Given a region position, return the parcel land object for that location
- ///
- ///
- /// The land object.
- ///
- ///
- ///
- ///
- /// Return null if the land object requested is not within the region's bounds.
- ///
- private ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds)
+ public ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds)
{
- if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
+ if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
{
// These exceptions here will cause a lot of complaints from the users specifically because
// they happen every time at border crossings
if (returnNullIfLandObjectOutsideBounds)
return null;
else
- throw new Exception(
- String.Format("{0} GetLandObject for non-existent position. Region={1}, pos=<{2},{3}",
- LogHeader, m_scene.RegionInfo.RegionName, x, y)
- );
+ throw new Exception("Error: Parcel not found at point " + x + ", " + y);
}
- return m_landList[m_landIDList[x / 4, y / 4]];
+ if(m_landList.Count == 0 || m_landIDList == null)
+ return null;
+
+ lock (m_landIDList)
+ {
+ try
+ {
+ return m_landList[m_landIDList[x / 4, y / 4]];
+ }
+ catch (IndexOutOfRangeException)
+ {
+ return null;
+ }
+ }
}
// Create a 'parcel is here' bitmap for the parcel identified by the passed landID
@@ -926,7 +1031,7 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
- public void FinalizeLandPrimCountUpdate()
+ private void FinalizeLandPrimCountUpdate()
{
//Get Simwide prim count for owner
Dictionary> landOwnersAndParcels = new Dictionary>();
@@ -967,10 +1072,10 @@ namespace OpenSim.Region.CoreModules.World.Land
public void EventManagerOnParcelPrimCountUpdate()
{
-// m_log.DebugFormat(
-// "[LAND MANAGEMENT MODULE]: Triggered EventManagerOnParcelPrimCountUpdate() for {0}",
-// m_scene.RegionInfo.RegionName);
-
+ //m_log.DebugFormat(
+ // "[land management module]: triggered eventmanageronparcelprimcountupdate() for {0}",
+ // m_scene.RegionInfo.RegionName);
+
ResetOverMeRecords();
EntityBase[] entities = m_scene.Entities.GetEntities();
foreach (EntityBase obj in entities)
@@ -1002,27 +1107,33 @@ namespace OpenSim.Region.CoreModules.World.Land
/// North Point
/// UUID of user who is trying to subdivide
/// Returns true if successful
- private void subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
+ public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
{
//First, lets loop through the points and make sure they are all in the same peice of land
//Get the land object at start
ILandObject startLandObject = GetLandObject(start_x, start_y);
- if (startLandObject == null) return;
+ if (startLandObject == null)
+ return;
+
+ if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin, true))
+ {
+ return;
+ }
//Loop through the points
try
{
- int totalX = end_x - start_x;
- int totalY = end_y - start_y;
- for (int y = 0; y < totalY; y++)
+ for (int y = start_y; y < end_y; y++)
{
- for (int x = 0; x < totalX; x++)
+ for (int x = start_x; x < end_x; x++)
{
- ILandObject tempLandObject = GetLandObject(start_x + x, start_y + y);
- if (tempLandObject == null) return;
- if (tempLandObject != startLandObject) return;
+ ILandObject tempLandObject = GetLandObject(x, y);
+ if (tempLandObject == null)
+ return;
+ if (tempLandObject != startLandObject)
+ return;
}
}
}
@@ -1031,22 +1142,22 @@ namespace OpenSim.Region.CoreModules.World.Land
return;
}
- //If we are still here, then they are subdividing within one piece of land
- //Check owner
- if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin))
- {
- return;
- }
-
- //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
+ //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
ILandObject newLand = startLandObject.Copy();
+
newLand.LandData.Name = newLand.LandData.Name;
newLand.LandData.GlobalID = UUID.Random();
newLand.LandData.Dwell = 0;
+ // Clear "Show in search" on the cut out parcel to prevent double-charging
+ newLand.LandData.Flags &= ~(uint)ParcelFlags.ShowDirectory;
+ // invalidate landing point
+ newLand.LandData.LandingType = (byte)LandingType.Direct;
+ newLand.LandData.UserLocation = Vector3.Zero;
+ newLand.LandData.UserLookAt = Vector3.Zero;
newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y));
- //Now, lets set the subdivision area of the original to false
+ //lets set the subdivision area of the original to false
int startLandObjectIndex = startLandObject.LandData.LocalID;
lock (m_landList)
{
@@ -1055,65 +1166,85 @@ namespace OpenSim.Region.CoreModules.World.Land
m_landList[startLandObjectIndex].ForceUpdateLandInfo();
}
- //Now add the new land object
+ //add the new land object
ILandObject result = AddLandObject(newLand);
- if (result != null)
+ UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData);
+
+ if(startLandObject.LandData.LandingType == (byte)LandingType.LandingPoint)
{
- UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData);
- result.SendLandUpdateToAvatarsOverMe();
- }
+ int x = (int)startLandObject.LandData.UserLocation.X;
+ int y = (int)startLandObject.LandData.UserLocation.Y;
+ if(!startLandObject.ContainsPoint(x, y))
+ {
+ startLandObject.LandData.LandingType = (byte)LandingType.Direct;
+ startLandObject.LandData.UserLocation = Vector3.Zero;
+ startLandObject.LandData.UserLookAt = Vector3.Zero;
+ }
+ }
+
+ m_scene.EventManager.TriggerParcelPrimCountTainted();
+
+ result.SendLandUpdateToAvatarsOverMe();
+ startLandObject.SendLandUpdateToAvatarsOverMe();
+ m_scene.ForEachClient(SendParcelOverlay);
+
}
///
/// Join 2 land objects together
///
- /// x value in first piece of land
- /// y value in first piece of land
- /// x value in second peice of land
- /// y value in second peice of land
+ /// start x of selection area
+ /// start y of selection area
+ /// end x of selection area
+ /// end y of selection area
/// UUID of the avatar trying to join the land objects
/// Returns true if successful
- private void join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
+ public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
{
- end_x -= 4;
- end_y -= 4;
+ int index = 0;
+ int maxindex = -1;
+ int maxArea = 0;
List selectedLandObjects = new List();
- int stepYSelected;
- for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4)
+ for (int x = start_x; x < end_x; x += 4)
{
- int stepXSelected;
- for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4)
+ for (int y = start_y; y < end_y; y += 4)
{
- ILandObject p = GetLandObject(stepXSelected, stepYSelected);
+ ILandObject p = GetLandObject(x, y);
if (p != null)
{
if (!selectedLandObjects.Contains(p))
{
selectedLandObjects.Add(p);
+ if(p.LandData.Area > maxArea)
+ {
+ maxArea = p.LandData.Area;
+ maxindex = index;
+ }
+ index++;
}
}
}
}
- ILandObject masterLandObject = selectedLandObjects[0];
- selectedLandObjects.RemoveAt(0);
- if (selectedLandObjects.Count < 1)
- {
+ if(maxindex < 0 || selectedLandObjects.Count < 2)
return;
- }
- if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin))
+
+ ILandObject masterLandObject = selectedLandObjects[maxindex];
+ selectedLandObjects.RemoveAt(maxindex);
+
+ if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin, true))
{
return;
}
+
+ UUID masterOwner = masterLandObject.LandData.OwnerID;
foreach (ILandObject p in selectedLandObjects)
{
- if (p.LandData.OwnerID != masterLandObject.LandData.OwnerID)
- {
+ if (p.LandData.OwnerID != masterOwner)
return;
- }
}
lock (m_landList)
@@ -1126,29 +1257,14 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
+ m_scene.EventManager.TriggerParcelPrimCountTainted();
masterLandObject.SendLandUpdateToAvatarsOverMe();
+ m_scene.ForEachClient(SendParcelOverlay);
}
-
- public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
- {
- join(start_x, start_y, end_x, end_y, attempting_user_id);
- }
-
- public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
- {
- subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
- }
-
#endregion
#region Parcel Updating
- // Send parcel layer info for the whole region
- public void SendParcelOverlay(IClientAPI remote_client)
- {
- SendParcelOverlay(remote_client, 0, 0, (int)Constants.MaximumRegionSize);
- }
-
///
/// Send the parcel overlay blocks to the client. We send the overlay packets
/// around a location and limited by the 'parcelLayerViewDistance'. This number
@@ -1162,145 +1278,115 @@ namespace OpenSim.Region.CoreModules.World.Land
/// X position in the region to send surrounding parcel layer info
/// y position in the region to send surrounding parcel layer info
/// Distance from x,y position to send parcel layer info
- private void SendParcelOverlay(IClientAPI remote_client, int xPlace, int yPlace, int layerViewDistance)
+ public void SendParcelOverlay(IClientAPI remote_client)
{
+ if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
+ return;
+
const int LAND_BLOCKS_PER_PACKET = 1024;
byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
int byteArrayCount = 0;
int sequenceID = 0;
- int xLow = 0;
- int xHigh = (int)m_scene.RegionInfo.RegionSizeX;
- int yLow = 0;
- int yHigh = (int)m_scene.RegionInfo.RegionSizeY;
-
- if (shouldLimitParcelLayerInfoToViewDistance)
+ // Layer data is in LandUnit (4m) chunks
+ for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y += LandUnit)
{
- // Compute view distance around the given point
- int txLow = xPlace - layerViewDistance;
- int txHigh = xPlace + layerViewDistance;
- // If the distance is outside the region area, move the view distance to ba all in the region
- if (txLow < xLow)
+ for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x += LandUnit)
{
- txLow = xLow;
- txHigh = Math.Min(yLow + (layerViewDistance * 2), xHigh);
- }
- if (txHigh > xHigh)
- {
- txLow = Math.Max(xLow, xHigh - (layerViewDistance * 2));
- txHigh = xHigh;
- }
- xLow = txLow;
- xHigh = txHigh;
+ byte tempByte = 0; //This represents the byte for the current 4x4
- int tyLow = yPlace - layerViewDistance;
- int tyHigh = yPlace + layerViewDistance;
- if (tyLow < yLow)
- {
- tyLow = yLow;
- tyHigh = Math.Min(yLow + (layerViewDistance * 2), yHigh);
- }
- if (tyHigh > yHigh)
- {
- tyLow = Math.Max(yLow, yHigh - (layerViewDistance * 2));
- tyHigh = yHigh;
- }
- yLow = tyLow;
- yHigh = tyHigh;
- }
- // m_log.DebugFormat("{0} SendParcelOverlay: place=<{1},{2}>, vDist={3}, xLH=<{4},{5}, yLH=<{6},{7}>",
- // LogHeader, xPlace, yPlace, layerViewDistance, xLow, xHigh, yLow, yHigh);
+ ILandObject currentParcelBlock = GetLandObject(x, y);
- // Layer data is in landUnit (4m) chunks
- for (int y = yLow; y < yHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
- {
- for (int x = xLow; x < xHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
- {
- byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * LandUnit, y * LandUnit), x, y, remote_client);
- byteArrayCount++;
- if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
+ if (currentParcelBlock != null)
{
- // m_log.DebugFormat("{0} SendParcelOverlay, sending packet, bytes={1}", LogHeader, byteArray.Length);
- remote_client.SendLandParcelOverlay(byteArray, sequenceID);
- byteArrayCount = 0;
- sequenceID++;
- byteArray = new byte[LAND_BLOCKS_PER_PACKET];
- }
+ // types
+ if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
+ {
+ //Owner Flag
+ tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
+ }
+ else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
+ {
+ tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_GROUP;
+ }
+ else if (currentParcelBlock.LandData.SalePrice > 0 &&
+ (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
+ currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
+ {
+ //Sale type
+ tempByte = (byte)LandChannel.LAND_TYPE_IS_FOR_SALE;
+ }
+ else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
+ {
+ //Public type
+ tempByte = (byte)LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero
+ }
+ // LAND_TYPE_IS_BEING_AUCTIONED still unsuported
+ else
+ {
+ //Other Flag
+ tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_OTHER;
+ }
- }
- }
+ // now flags
+ // border control
- if (byteArrayCount != 0)
- {
- remote_client.SendLandParcelOverlay(byteArray, sequenceID);
- // m_log.DebugFormat("{0} SendParcelOverlay, complete sending packet, bytes={1}", LogHeader, byteArray.Length);
- }
- }
+ ILandObject westParcel = null;
+ ILandObject southParcel = null;
+ if (x > 0)
+ {
+ westParcel = GetLandObject((x - 1), y);
+ }
+ if (y > 0)
+ {
+ southParcel = GetLandObject(x, (y - 1));
+ }
- private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client)
- {
- byte tempByte = 0; //This represents the byte for the current 4x4
+ if (x == 0)
+ {
+ tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
+ }
+ else if (westParcel != null && westParcel != currentParcelBlock)
+ {
+ tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
+ }
- if (currentParcelBlock != null)
- {
- if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
- {
- //Owner Flag
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
- }
- else if (currentParcelBlock.LandData.SalePrice > 0 &&
- (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
- currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
- {
- //Sale Flag
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
- }
- else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
- {
- //Public Flag
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
- }
- else
- {
- //Other Flag
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
- }
+ if (y == 0)
+ {
+ tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
+ }
+ else if (southParcel != null && southParcel != currentParcelBlock)
+ {
+ tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
+ }
- //Now for border control
+ // local sound
+ if ((currentParcelBlock.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
+ tempByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
- ILandObject westParcel = null;
- ILandObject southParcel = null;
- if (x > 0)
- {
- westParcel = GetLandObject((x - 1) * LandUnit, y * LandUnit);
- }
- if (y > 0)
- {
- southParcel = GetLandObject(x * LandUnit, (y - 1) * LandUnit);
- }
+ // hide avatars
+ if (!currentParcelBlock.LandData.SeeAVs)
+ tempByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS;
- if (x == 0)
- {
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
- }
- else if (westParcel != null && westParcel != currentParcelBlock)
- {
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
- }
- if (y == 0)
- {
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
- }
- else if (southParcel != null && southParcel != currentParcelBlock)
- {
- tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
+ byteArray[byteArrayCount] = tempByte;
+ byteArrayCount++;
+ if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
+ {
+ remote_client.SendLandParcelOverlay(byteArray, sequenceID);
+ byteArrayCount = 0;
+ sequenceID++;
+ byteArray = new byte[LAND_BLOCKS_PER_PACKET];
+ }
+ }
}
-
}
- return tempByte;
+ if (byteArrayCount > 0)
+ {
+ remote_client.SendLandParcelOverlay(byteArray, sequenceID);
+ }
}
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
{
if (!temp.Contains(currentParcel))
{
- currentParcel.ForceUpdateLandInfo();
- temp.Add(currentParcel);
+ if (!currentParcel.IsBannedFromLand(remote_client.AgentId))
+ {
+ currentParcel.ForceUpdateLandInfo();
+ temp.Add(currentParcel);
+ }
}
}
}
@@ -1338,8 +1427,44 @@ namespace OpenSim.Region.CoreModules.World.Land
temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client);
}
- // Also send the layer data around the point of interest
- SendParcelOverlay(remote_client, (start_x + end_x) / 2, (start_y + end_y) / 2, parcelLayerViewDistance);
+// SendParcelOverlay(remote_client);
+ }
+
+ public void UpdateLandProperties(ILandObject land, LandUpdateArgs args, IClientAPI remote_client)
+ {
+ bool snap_selection = false;
+ bool needOverlay = false;
+ if (land.UpdateLandProperties(args, remote_client, out snap_selection, out needOverlay))
+ {
+ UUID parcelID = land.LandData.GlobalID;
+ m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
+ {
+ if (avatar.IsDeleted || avatar.IsNPC)
+ return;
+
+ IClientAPI client = avatar.ControllingClient;
+ if (needOverlay)
+ SendParcelOverlay(client);
+
+ if (avatar.IsChildAgent)
+ {
+ if(client == remote_client)
+ land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, client);
+ return;
+ }
+
+ ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
+ if (aland != null)
+ {
+ if(client == remote_client && land != aland)
+ land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, client);
+ else if (land == aland)
+ aland.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, client);
+ }
+ if (avatar.currentParcelUUID == parcelID)
+ avatar.currentParcelUUID = parcelID; // force parcel flags review
+ });
+ }
}
public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client)
@@ -1352,19 +1477,19 @@ namespace OpenSim.Region.CoreModules.World.Land
if (land != null)
{
- land.UpdateLandProperties(args, remote_client);
+ UpdateLandProperties(land, args, remote_client);
m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client);
}
}
public void ClientOnParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
{
- subdivide(west, south, east, north, remote_client.AgentId);
+ Subdivide(west, south, east, north, remote_client.AgentId);
}
public void ClientOnParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client)
{
- join(west, south, east, north, remote_client.AgentId);
+ Join(west, south, east, north, remote_client.AgentId);
}
public void ClientOnParcelSelectObjects(int local_id, int request_type,
@@ -1375,7 +1500,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void ClientOnParcelObjectOwnerRequest(int local_id, IClientAPI remote_client)
{
- ILandObject land;
+ ILandObject land = null;
lock (m_landList)
{
m_landList.TryGetValue(local_id, out land);
@@ -1384,7 +1509,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if (land != null)
{
m_scene.EventManager.TriggerParcelPrimCountUpdate();
- m_landList[local_id].SendLandObjectOwners(remote_client);
+ land.SendLandObjectOwners(remote_client);
}
else
{
@@ -1394,7 +1519,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void ClientOnParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client)
{
- ILandObject land;
+ ILandObject land = null;
lock (m_landList)
{
m_landList.TryGetValue(local_id, out land);
@@ -1408,7 +1533,6 @@ namespace OpenSim.Region.CoreModules.World.Land
land.LandData.GroupID = UUID.Zero;
land.LandData.IsGroupOwned = false;
land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
-
m_scene.ForEachClient(SendParcelOverlay);
land.SendLandUpdateToClient(true, remote_client);
UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1418,7 +1542,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void ClientOnParcelAbandonRequest(int local_id, IClientAPI remote_client)
{
- ILandObject land;
+ ILandObject land = null;
lock (m_landList)
{
m_landList.TryGetValue(local_id, out land);
@@ -1432,7 +1556,7 @@ namespace OpenSim.Region.CoreModules.World.Land
land.LandData.GroupID = UUID.Zero;
land.LandData.IsGroupOwned = false;
land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
-
+
m_scene.ForEachClient(SendParcelOverlay);
land.SendLandUpdateToClient(true, remote_client);
UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1442,7 +1566,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void ClientOnParcelReclaim(int local_id, IClientAPI remote_client)
{
- ILandObject land;
+ ILandObject land = null;
lock (m_landList)
{
m_landList.TryGetValue(local_id, out land);
@@ -1458,8 +1582,10 @@ namespace OpenSim.Region.CoreModules.World.Land
land.LandData.IsGroupOwned = false;
land.LandData.SalePrice = 0;
land.LandData.AuthBuyerID = UUID.Zero;
+ land.LandData.SeeAVs = true;
+ land.LandData.AnyAVSounds = true;
+ land.LandData.GroupAVSounds = true;
land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
-
m_scene.ForEachClient(SendParcelOverlay);
land.SendLandUpdateToClient(true, remote_client);
UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1526,17 +1652,16 @@ namespace OpenSim.Region.CoreModules.World.Land
void ClientOnParcelDeedToGroup(int parcelLocalID, UUID groupID, IClientAPI remote_client)
{
- ILandObject land;
+ ILandObject land = null;
lock (m_landList)
{
m_landList.TryGetValue(parcelLocalID, out land);
}
- if (!m_scene.Permissions.CanDeedParcel(remote_client.AgentId, land))
- return;
-
if (land != null)
{
+ if (!m_scene.Permissions.CanDeedParcel(remote_client.AgentId, land))
+ return;
land.DeedToGroup(groupID);
}
}
@@ -1545,17 +1670,12 @@ namespace OpenSim.Region.CoreModules.World.Land
private void EventManagerOnIncomingLandDataFromStorage(List data)
{
-// m_log.DebugFormat(
-// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name);
-
- // Prevent race conditions from any auto-creation of new parcels for varregions whilst we are still loading
- // the existing parcels.
lock (m_landList)
{
for (int i = 0; i < data.Count; i++)
IncomingLandObjectFromStorage(data[i]);
- // Layer data is in landUnit (4m) chunks
+ // Layer data is in LandUnit (4m) chunks
for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
{
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
if (m_landList.Count == 1)
{
m_log.DebugFormat(
- "[{0}]: Auto-extending land parcel as landID at {1},{2} is 0 and only one land parcel is present in {3}",
+ "[{0}]: Auto-extending land parcel as landID at {1},{2} is 0 and only one land parcel is present in {3}",
LogHeader, x, y, m_scene.Name);
int onlyParcelID = 0;
@@ -1588,11 +1708,11 @@ namespace OpenSim.Region.CoreModules.World.Land
else if (m_landList.Count > 1)
{
m_log.DebugFormat(
- "{0}: Auto-creating land parcel as landID at {1},{2} is 0 and more than one land parcel is present in {3}",
+ "{0}: Auto-creating land parcel as landID at {1},{2} is 0 and more than one land parcel is present in {3}",
LogHeader, x, y, m_scene.Name);
// There are several other parcels so we must create a new one for the unassigned space
- ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
+ ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
// Claim all the unclaimed "0" ids
newLand.SetLandBitmap(CreateBitmapForID(0));
newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@@ -1603,20 +1723,23 @@ namespace OpenSim.Region.CoreModules.World.Land
{
// We should never reach this point as the separate code path when no land data exists should have fired instead.
m_log.WarnFormat(
- "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present",
+ "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present",
LogHeader, m_scene.Name);
}
}
}
}
+ FinalizeLandPrimCountUpdate(); // update simarea information
}
}
private void IncomingLandObjectFromStorage(LandData data)
{
- ILandObject new_land = new LandObject(data, m_scene);
- new_land.SetLandBitmapFromByteArray();
+ ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene, data);
+
+ new_land.SetLandBitmapFromByteArray();
AddLandObject(new_land);
+// new_land.SendLandUpdateToAvatarsOverMe();
}
public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1629,7 +1752,7 @@ namespace OpenSim.Region.CoreModules.World.Land
m_landList.TryGetValue(localID, out selectedParcel);
}
- if (selectedParcel == null)
+ if (selectedParcel == null)
return;
selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient);
@@ -1670,9 +1793,9 @@ namespace OpenSim.Region.CoreModules.World.Land
foreach (HashSet objs in returns.Values)
{
List objs2 = new List(objs);
- if (m_scene.Permissions.CanReturnObjects(null, remoteClient.AgentId, objs2))
+ if (m_scene.Permissions.CanReturnObjects(null, remoteClient, objs2))
{
- m_scene.returnObjects(objs2.ToArray(), remoteClient.AgentId);
+ m_scene.returnObjects(objs2.ToArray(), remoteClient);
}
else
{
@@ -1710,12 +1833,13 @@ namespace OpenSim.Region.CoreModules.World.Land
private void EventManagerOnRegisterCaps(UUID agentID, Caps caps)
{
+ //string capsBase = "/CAPS/" + UUID.Random();
string capsBase = "/CAPS/" + caps.CapsObjectPath;
caps.RegisterHandler(
"RemoteParcelRequest",
new RestStreamHandler(
"POST",
- capsBase + remoteParcelRequestPath,
+ capsBase,
(request, path, param, httpRequest, httpResponse)
=> RemoteParcelRequest(request, path, param, agentID, caps),
"RemoteParcelRequest",
@@ -1735,7 +1859,7 @@ namespace OpenSim.Region.CoreModules.World.Land
private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps)
{
IClientAPI client;
- if (!m_scene.TryGetClient(agentID, out client))
+ if (!m_scene.TryGetClient(agentID, out client))
{
m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to retrieve IClientAPI for {0}", agentID);
return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
@@ -1759,7 +1883,7 @@ namespace OpenSim.Region.CoreModules.World.Land
land_update.MusicURL = properties.MusicURL;
land_update.Name = properties.Name;
land_update.ParcelFlags = (uint) properties.ParcelFlags;
- land_update.PassHours = (int) properties.PassHours;
+ land_update.PassHours = properties.PassHours;
land_update.PassPrice = (int) properties.PassPrice;
land_update.SalePrice = (int) properties.SalePrice;
land_update.SnapshotID = properties.SnapshotID;
@@ -1773,7 +1897,20 @@ namespace OpenSim.Region.CoreModules.World.Land
land_update.ObscureMusic = properties.ObscureMusic;
land_update.ObscureMedia = properties.ObscureMedia;
- ILandObject land;
+ if (args.ContainsKey("see_avs"))
+ {
+ land_update.SeeAVs = args["see_avs"].AsBoolean();
+ land_update.AnyAVSounds = args["any_av_sounds"].AsBoolean();
+ land_update.GroupAVSounds = args["group_av_sounds"].AsBoolean();
+ }
+ else
+ {
+ land_update.SeeAVs = true;
+ land_update.AnyAVSounds = true;
+ land_update.GroupAVSounds = true;
+ }
+
+ ILandObject land = null;
lock (m_landList)
{
m_landList.TryGetValue(parcelID, out land);
@@ -1781,13 +1918,14 @@ namespace OpenSim.Region.CoreModules.World.Land
if (land != null)
{
- land.UpdateLandProperties(land_update, client);
+ UpdateLandProperties(land,land_update, client);
m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client);
}
else
{
m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID);
}
+
return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
}
// 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
{
Hashtable hash = new Hashtable();
hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
- if (hash.ContainsKey("region_id") && hash.ContainsKey("location"))
+ if (hash.ContainsKey("location"))
{
- UUID regionID = (UUID)hash["region_id"];
+ UUID scope = m_scene.RegionInfo.ScopeID;
ArrayList list = (ArrayList)hash["location"];
uint x = (uint)(double)list[0];
uint y = (uint)(double)list[1];
@@ -1826,19 +1964,46 @@ namespace OpenSim.Region.CoreModules.World.Land
// if you do a "About Landmark" on a landmark a second time, the viewer sends the
// region_handle it got earlier via RegionHandleRequest
ulong regionHandle = Util.BytesToUInt64Big((byte[])hash["region_handle"]);
- parcelID = Util.BuildFakeParcelID(regionHandle, x, y);
+ if(regionHandle == m_scene.RegionInfo.RegionHandle)
+ parcelID = Util.BuildFakeParcelID(regionHandle, x, y);
+ else
+ {
+ uint wx;
+ uint wy;
+ Util.RegionHandleToWorldLoc(regionHandle, out wx, out wy);
+ GridRegion info = m_scene.GridService.GetRegionByPosition(scope, (int)wx, (int)wy);
+ if(info != null)
+ {
+ wx -= (uint)info.RegionLocX;
+ wy -= (uint)info.RegionLocY;
+ wx += x;
+ wy += y;
+ // Firestorm devs have no ideia how to do handlers math
+ // on all cases
+ if(wx > info.RegionSizeX || wy > info.RegionSizeY)
+ {
+ wx = x;
+ wy = y;
+ }
+ parcelID = Util.BuildFakeParcelID(info.RegionHandle, wx, wy);
+ }
+ }
}
- else if (regionID == m_scene.RegionInfo.RegionID)
+ else if(hash.ContainsKey("region_id"))
{
+ UUID regionID = (UUID)hash["region_id"];
+ if (regionID == m_scene.RegionInfo.RegionID)
+ {
// a parcel request for a local parcel => no need to query the grid
- parcelID = Util.BuildFakeParcelID(m_scene.RegionInfo.RegionHandle, x, y);
- }
- else
- {
- // a parcel request for a parcel in another region. Ask the grid about the region
- GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, regionID);
- if (info != null)
- parcelID = Util.BuildFakeParcelID(info.RegionHandle, x, y);
+ parcelID = Util.BuildFakeParcelID(m_scene.RegionInfo.RegionHandle, x, y);
+ }
+ else
+ {
+ // a parcel request for a parcel in another region. Ask the grid about the region
+ GridRegion info = m_scene.GridService.GetRegionByUUID(scope, regionID);
+ if (info != null)
+ parcelID = Util.BuildFakeParcelID(info.RegionHandle, x, y);
+ }
}
}
}
@@ -1854,7 +2019,7 @@ namespace OpenSim.Region.CoreModules.World.Land
LLSDRemoteParcelResponse response = new LLSDRemoteParcelResponse();
response.parcel_id = parcelID;
- m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelID {0}", parcelID);
+ //m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelID {0}", parcelID);
return LLSDHelpers.SerialiseLLSDReply(response);
}
@@ -1871,17 +2036,25 @@ namespace OpenSim.Region.CoreModules.World.Land
{
UUID parcel = UUID.Zero;
UUID.TryParse(id, out parcel);
+
// assume we've got the parcelID we just computed in RemoteParcelRequest
ExtendedLandData extLandData = new ExtendedLandData();
- Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle,
- out extLandData.X, out extLandData.Y);
- m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelinfo request for regionHandle {0}, x/y {1}/{2}",
+ if(!Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle,
+ out extLandData.X, out extLandData.Y))
+ return null;
+ m_log.DebugFormat("[LAND MANAGEMENT MODULE] : Got parcelinfo request for regionHandle {0}, x/y {1}/{2}",
extLandData.RegionHandle, extLandData.X, extLandData.Y);
// for this region or for somewhere else?
if (extLandData.RegionHandle == m_scene.RegionInfo.RegionHandle)
{
- extLandData.LandData = this.GetLandObject(extLandData.X, extLandData.Y).LandData;
+ ILandObject extLandObject = this.GetLandObject(extLandData.X, extLandData.Y);
+ if(extLandObject == null)
+ {
+ m_log.DebugFormat("[LAND MANAGEMENT MODULE]: ParcelInfoRequest: a FakeParcelID points to outside the region");
+ return null;
+ }
+ extLandData.LandData = extLandObject.LandData;
extLandData.RegionAccess = m_scene.RegionInfo.AccessLevel;
}
else
@@ -1907,6 +2080,9 @@ namespace OpenSim.Region.CoreModules.World.Land
if (data.RegionHandle == m_scene.RegionInfo.RegionHandle)
{
info = new GridRegion(m_scene.RegionInfo);
+ IDwellModule dwellModule = m_scene.RequestModuleInterface();
+ if (dwellModule != null)
+ data.LandData.Dwell = dwellModule.GetDwell(data.LandData);
}
else
{
@@ -1932,7 +2108,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)
{
- ILandObject land;
+ ILandObject land = null;
lock (m_landList)
{
m_landList.TryGetValue(localID, out land);
@@ -1940,14 +2116,91 @@ namespace OpenSim.Region.CoreModules.World.Land
if (land == null) return;
- if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions))
+ if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions, false))
return;
land.LandData.OtherCleanTime = otherCleanTime;
UpdateLandObject(localID, land.LandData);
}
-
+
+ public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
+ {
+ ILandObject land = null;
+ List Land = ((Scene)client.Scene).LandChannel.AllParcels();
+ foreach (ILandObject landObject in Land)
+ {
+ if (landObject.LandData.LocalID == landID)
+ {
+ land = landObject;
+ }
+ }
+ land.DeedToGroup(DefaultGodParcelGroup);
+ land.LandData.Name = DefaultGodParcelName;
+ land.SendLandUpdateToAvatarsOverMe();
+ }
+
+ private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
+ {
+ ScenePresence SP;
+ ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
+ List returns = new List();
+ if (SP.GodController.UserLevel != 0)
+ {
+ if (flags == 0) //All parcels, scripted or not
+ {
+ ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
+ {
+ if (e.OwnerID == targetID)
+ {
+ returns.Add(e);
+ }
+ }
+ );
+ }
+ if (flags == 4) //All parcels, scripted object
+ {
+ ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
+ {
+ if (e.OwnerID == targetID)
+ {
+ if (e.ContainsScripts())
+ {
+ returns.Add(e);
+ }
+ }
+ });
+ }
+ if (flags == 4) //not target parcel, scripted object
+ {
+ ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
+ {
+ if (e.OwnerID == targetID)
+ {
+ ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
+ if (landobject.LandData.OwnerID != e.OwnerID)
+ {
+ if (e.ContainsScripts())
+ {
+ returns.Add(e);
+ }
+ }
+ }
+ });
+ }
+ foreach (SceneObjectGroup ol in returns)
+ {
+ ReturnObject(ol, client);
+ }
+ }
+ }
+ public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
+ {
+ SceneObjectGroup[] objs = new SceneObjectGroup[1];
+ objs[0] = obj;
+ ((Scene)client.Scene).returnObjects(objs, client);
+ }
+
Dictionary Timers = new Dictionary();
public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
@@ -1958,12 +2211,12 @@ namespace OpenSim.Region.CoreModules.World.Land
((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager);
System.Threading.Timer Timer;
- if (targetAvatar.UserLevel == 0)
+ if (targetAvatar.GodController.UserLevel < 200)
{
ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
- if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze))
+ if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true))
return;
- if (flags == 0)
+ if ((flags & 1) == 0) // only lowest bit has meaning for now
{
targetAvatar.AllowMovement = false;
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
}
}
}
-
private void OnEndParcelFrozen(object avatar)
{
ScenePresence targetAvatar = (ScenePresence)avatar;
@@ -2010,12 +2262,13 @@ namespace OpenSim.Region.CoreModules.World.Land
// Check if you even have permission to do this
ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
- if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) &&
+ if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true) &&
!m_scene.Permissions.IsAdministrator(client.AgentId))
return;
+
Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
- targetAvatar.TeleportWithMomentum(pos, null);
+ targetAvatar.TeleportOnEject(pos);
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
@@ -2059,7 +2312,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if (// Required: local user; foreign users cannot set home
m_scene.UserManagementModule.IsLocalGridUser(remoteClient.AgentId) &&
(// (a) gods and land managers can set home
- m_scene.Permissions.IsAdministrator(remoteClient.AgentId) ||
+ m_scene.Permissions.IsAdministrator(remoteClient.AgentId) ||
m_scene.Permissions.IsGod(remoteClient.AgentId) ||
// (b) land owners can set home
remoteClient.AgentId == land.LandData.OwnerID ||
@@ -2111,8 +2364,8 @@ namespace OpenSim.Region.CoreModules.World.Land
"If no local land ID is given, then summary information about all the parcels is shown.\n"
+ "If a local land ID is given then full information about that parcel is shown.",
HandleShowCommand);
- }
-
+ }
+
protected void HandleClearCommand(string module, string[] args)
{
if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
@@ -2120,9 +2373,9 @@ namespace OpenSim.Region.CoreModules.World.Land
string response = MainConsole.Instance.CmdPrompt(
string.Format(
- "Are you sure that you want to clear all land parcels from {0} (y or n)", m_scene.Name),
+ "Are you sure that you want to clear all land parcels from {0} (y or n)", m_scene.Name),
"n");
-
+
if (response.ToLower() == "y")
{
Clear(true);
@@ -2132,14 +2385,14 @@ namespace OpenSim.Region.CoreModules.World.Land
{
MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.Name);
}
- }
-
+ }
+
protected void HandleShowCommand(string module, string[] args)
{
if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
return;
- StringBuilder report = new StringBuilder();
+ StringBuilder report = new StringBuilder();
if (args.Length <= 2)
{
@@ -2152,10 +2405,10 @@ namespace OpenSim.Region.CoreModules.World.Land
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[2], out landLocalId))
return;
- ILandObject lo;
+ ILandObject lo = null;
lock (m_landList)
- {
+ {
if (!m_landList.TryGetValue(landLocalId, out lo))
{
MainConsole.Instance.OutputFormat("No parcel found with local ID {0}", landLocalId);
@@ -2170,7 +2423,7 @@ namespace OpenSim.Region.CoreModules.World.Land
}
private void AppendParcelsSummaryReport(StringBuilder report)
- {
+ {
report.AppendFormat("Land information for {0}\n", m_scene.Name);
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
@@ -2180,7 +2433,7 @@ namespace OpenSim.Region.CoreModules.World.Land
cdt.AddColumn("Starts", ConsoleDisplayUtil.VectorSize);
cdt.AddColumn("Ends", ConsoleDisplayUtil.VectorSize);
cdt.AddColumn("Owner", ConsoleDisplayUtil.UserNameSize);
-
+
lock (m_landList)
{
foreach (ILandObject lo in m_landList.Values)
@@ -2202,7 +2455,7 @@ namespace OpenSim.Region.CoreModules.World.Land
}
report.Append(cdt.ToString());
- }
+ }
private void AppendParcelReport(StringBuilder report, ILandObject lo)
{
@@ -2214,8 +2467,6 @@ namespace OpenSim.Region.CoreModules.World.Land
cdl.AddRow("Description", ld.Description);
cdl.AddRow("Snapshot ID", ld.SnapshotID);
cdl.AddRow("Area", ld.Area);
- cdl.AddRow("Starts", lo.StartPoint);
- cdl.AddRow("Ends", lo.EndPoint);
cdl.AddRow("AABB Min", ld.AABBMin);
cdl.AddRow("AABB Max", ld.AABBMax);
string ownerName;
@@ -2233,7 +2484,7 @@ namespace OpenSim.Region.CoreModules.World.Land
cdl.AddRow("GroupID", ld.GroupID);
cdl.AddRow("Status", ld.Status);
- cdl.AddRow("Flags", (ParcelFlags)ld.Flags);
+ cdl.AddRow("Flags", (ParcelFlags)ld.Flags);
cdl.AddRow("Landing Type", (LandingType)ld.LandingType);
cdl.AddRow("User Location", ld.UserLocation);
@@ -2242,12 +2493,14 @@ namespace OpenSim.Region.CoreModules.World.Land
cdl.AddRow("Other clean time", ld.OtherCleanTime);
cdl.AddRow("Max Prims", lo.GetParcelMaxPrimCount());
+ cdl.AddRow("Simwide Max Prims (owner)", lo.GetSimulatorMaxPrimCount());
IPrimCounts pc = lo.PrimCounts;
cdl.AddRow("Owner Prims", pc.Owner);
cdl.AddRow("Group Prims", pc.Group);
cdl.AddRow("Other Prims", pc.Others);
cdl.AddRow("Selected Prims", pc.Selected);
cdl.AddRow("Total Prims", pc.Total);
+ cdl.AddRow("SimWide Prims (owner)", pc.Simulator);
cdl.AddRow("Music URL", ld.MusicURL);
cdl.AddRow("Obscure Music", ld.ObscureMusic);
--
cgit v1.1