diff --git a/OpenSim/Framework/ConfigurationMember.cs b/OpenSim/Framework/ConfigurationMember.cs index cb434f0844..c363ec0cab 100644 --- a/OpenSim/Framework/ConfigurationMember.cs +++ b/OpenSim/Framework/ConfigurationMember.cs @@ -420,7 +420,7 @@ namespace OpenSim.Framework case ConfigurationOption.ConfigurationTypes.TYPE_FLOAT: float floatResult; if ( - float.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo, + float.TryParse(console_result, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Culture.NumberFormatInfo, out floatResult)) { convertSuccess = true; @@ -431,7 +431,7 @@ namespace OpenSim.Framework case ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE: double doubleResult; if ( - Double.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo, + Double.TryParse(console_result, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Culture.NumberFormatInfo, out doubleResult)) { convertSuccess = true; @@ -519,4 +519,4 @@ namespace OpenSim.Framework configurationPlugin.Close(); } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs index d0e56ab86e..997caad6c1 100644 --- a/OpenSim/Framework/EstateSettings.cs +++ b/OpenSim/Framework/EstateSettings.cs @@ -773,9 +773,9 @@ namespace OpenSim.Framework configMember.addConfigurationOption("sun_hour", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "0", true); configMember.addConfigurationOption("terrain_raise_limit", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, - String.Empty, "0", true); + String.Empty, "4.0", true); //4 is the LL default configMember.addConfigurationOption("terrain_lower_limit", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, - String.Empty, "0", true); + String.Empty, "-4.0", true); //-4.0 is the LL default configMember.addConfigurationOption("use_fixed_sun", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, String.Empty, "false", true); configMember.addConfigurationOption("price_per_meter", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, @@ -1013,4 +1013,4 @@ namespace OpenSim.Framework return true; } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index fafd31d4d8..e4fac1f1e4 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -410,7 +410,7 @@ namespace OpenSim.Framework public delegate void ModifyTerrain( float height, float seconds, byte size, byte action, float north, float west, float south, float east, IClientAPI remoteClient); - + public delegate void SetAppearance(byte[] texture, List visualParamList); public delegate void StartAnim(IClientAPI remoteClient, LLUUID animID); @@ -633,6 +633,7 @@ namespace OpenSim.Framework public delegate void SetEstateTerrainTextureHeights(IClientAPI remoteClient, int corner, float lowVal, float highVal); public delegate void CommitEstateTerrainTextureRequest(IClientAPI remoteClient); public delegate void SetRegionTerrainSettings(float waterHeight, float terrainRaiseLimit, float terrainLowerLimit, bool fixedSun, float sunHour); + public delegate void BakeTerrain(IClientAPI remoteClient ); public delegate void EstateRestartSimRequest(IClientAPI remoteClient, int secondsTilReboot); public delegate void EstateChangeCovenantRequest(IClientAPI remoteClient, LLUUID newCovenantID); public delegate void UpdateEstateAccessDeltaRequest(IClientAPI remote_client, LLUUID invoice, int estateAccessType, LLUUID user); @@ -693,6 +694,7 @@ namespace OpenSim.Framework event RezObject OnRezObject; [Obsolete("LLClientView Specific - Replace with more suitable arguments.")] event ModifyTerrain OnModifyTerrain; + event BakeTerrain OnBakeTerrain; [Obsolete("LLClientView Specific.")] event SetAppearance OnSetAppearance; [Obsolete("LLClientView Specific - Replace and rename OnAvatarUpdate. Difference from SetAppearance?")] diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index b298578d64..3dddbfb6e2 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -159,6 +159,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private RezObject handlerRezObject = null; //OnRezObject; private GenericCall4 handlerDeRezObject = null; //OnDeRezObject; private ModifyTerrain handlerModifyTerrain = null; + private BakeTerrain handlerBakeTerrain = null; private Action handlerRegionHandShakeReply = null; //OnRegionHandShakeReply; private GenericCall2 handlerRequestWearables = null; //OnRequestWearables; private Action handlerRequestAvatarsData = null; //OnRequestAvatarsData; @@ -893,6 +894,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights; public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest; public event SetRegionTerrainSettings OnSetRegionTerrainSettings; + public event BakeTerrain OnBakeTerrain; public event EstateRestartSimRequest OnEstateRestartSimRequest; public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest; public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest; @@ -5846,6 +5848,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerLandStatRequest(0, 0, 0, "", this); } break; + case "terrain": + if (((Scene)m_scene).ExternalChecks.ExternalChecksCanIssueEstateCommand(this.AgentId)) + { + handlerBakeTerrain = OnBakeTerrain; + if (handlerBakeTerrain != null) + { + handlerBakeTerrain(this); + } + } + break; + default: m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket.ToString()); break; diff --git a/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs b/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs index 4935672e01..a242ebe822 100644 --- a/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs @@ -281,6 +281,7 @@ namespace OpenSim.Region.Environment.Modules.World.NPC public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights; public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest; public event SetRegionTerrainSettings OnSetRegionTerrainSettings; + public event BakeTerrain OnBakeTerrain; public event EstateRestartSimRequest OnEstateRestartSimRequest; public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest; public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest; @@ -776,5 +777,6 @@ namespace OpenSim.Region.Environment.Modules.World.NPC { } #endregion - } + + } } diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs index 9d8bbfcb96..49347b250c 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs @@ -419,12 +419,27 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain private void EventManager_OnNewClient(IClientAPI client) { client.OnModifyTerrain += client_OnModifyTerrain; + client.OnBakeTerrain += client_OnBakeTerrain; } /// /// Checks to see if the terrain has been modified since last check + /// but won't attempt to limit those changes to the limits specified in the estate settings + /// currently invoked by the command line operations in the region server only /// private void CheckForTerrainUpdates() + { + CheckForTerrainUpdates(false); + } + + /// + /// Checks to see if the terrain has been modified since last check + /// if the call is asked to respect the estate settings for terrain_raise_limit and + /// terrain_lower_limit, it will clamp terrain updates between these values + /// currently invoked by client_OnModifyTerrain only and not the Commander interfaces + /// should height map deltas be limited to the estate settings limits + /// + private void CheckForTerrainUpdates(bool respectEstateSettings) { bool shouldTaint = false; float[] serialised = m_channel.GetFloatsSerialised(); @@ -436,6 +451,14 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain { if (m_channel.Tainted(x, y)) { + // if we should respect the estate settings then + // fixup and height deltas that don't respect them + if (respectEstateSettings && LimitChannelChanges(x, y)) + { + // this has been vetoed, so update + // what we are going to send to the client + serialised = m_channel.GetFloatsSerialised(); + } SendToClients(serialised, x, y); shouldTaint = true; } @@ -447,6 +470,46 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain } } + + /// + /// Checks to see height deltas in the tainted terrain patch at xStart ,yStart + /// are all within the current estate limits + /// true if changes were limited, false otherwise + /// + private bool LimitChannelChanges(int xStart, int yStart) + { + bool changesLimited = false; + double minDelta = m_scene.RegionInfo.EstateSettings.terrainLowerLimit; + double maxDelta = m_scene.RegionInfo.EstateSettings.terrainRaiseLimit; + + // loop through the height map for this patch and compare it against + // the revert map + for (int x = xStart; x < xStart + Constants.TerrainPatchSize; x++) + { + for (int y = yStart; y < yStart + Constants.TerrainPatchSize; y++) + { + + double requestedHeight = m_channel[x, y]; + double bakedHeight = m_revert[x, y]; + double requestedDelta = requestedHeight - bakedHeight; + + if (requestedDelta > maxDelta ) + { + m_channel[x, y] = bakedHeight + maxDelta; + changesLimited = true; + } + else if (requestedDelta < minDelta) + { + m_channel[x, y] = bakedHeight + minDelta; //as lower is a -ve delta + changesLimited = true; + } + } + } + + return changesLimited; + } + + /// /// Sends a copy of the current terrain to the scenes clients /// @@ -472,7 +535,7 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain m_painteffects[(StandardTerrainEffects) action].PaintEffect( m_channel, west, south, size, seconds); - CheckForTerrainUpdates(); + CheckForTerrainUpdates(true); //revert changes outside estate limits } else { @@ -505,7 +568,7 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain m_floodeffects[(StandardTerrainEffects) action].FloodEffect( m_channel, fillArea, size); - CheckForTerrainUpdates(); + CheckForTerrainUpdates(true); //revert changes outside estate limits } else { @@ -515,6 +578,18 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain } } + private void client_OnBakeTerrain(IClientAPI remoteClient) + { + // Not a good permissions check (see client_OnModifyTerrain above), need to check the entire area. + // for now check a point in the centre of the region + + if (m_scene.ExternalChecks.ExternalChecksCanTerraformLand(remoteClient.AgentId, new LLVector3(127, 127, 0))) + { + InterfaceBakeTerrain(null); //bake terrain does not use the passed in parameter + } + } + + #region Console Commands private void InterfaceLoadFile(Object[] args) @@ -745,4 +820,4 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 6ff600f4fa..0f7a057651 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -57,6 +57,7 @@ namespace OpenSim.Region.Examples.SimpleModule public event TextureRequest OnRequestTexture; public event RezObject OnRezObject; public event ModifyTerrain OnModifyTerrain; + public event BakeTerrain OnBakeTerrain; public event SetAppearance OnSetAppearance; public event AvatarNowWearing OnAvatarNowWearing; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;