diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs index 9f5991b70a..1a5ecd647e 100644 --- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs +++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs @@ -531,10 +531,14 @@ ELSE /// public double[,] LoadTerrain(UUID regionID) { + double[,] ret = null; TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); - return terrData.GetDoubles(); + if (terrData != null) + ret = terrData.GetDoubles(); + return ret; } + // Returns 'null' if region not found public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) { TerrainData terrData = null; diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 42f2ebb71f..2921c1c8db 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -616,10 +616,14 @@ namespace OpenSim.Data.MySQL // Legacy region loading public double[,] LoadTerrain(UUID regionID) { + double[,] ret = null; TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); - return terrData.GetDoubles(); + if (terrData != null) + ret = terrData.GetDoubles(); + return ret; } + // Returns 'null' if region not found public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) { TerrainData terrData = null; diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs index acde1a164c..deeaced294 100644 --- a/OpenSim/Data/Null/NullSimulationData.cs +++ b/OpenSim/Data/Null/NullSimulationData.cs @@ -148,6 +148,7 @@ namespace OpenSim.Data.Null } // Legacy. Just don't do this. + // Returns 'null' if region not found public double[,] LoadTerrain(UUID regionID) { if (m_terrains.ContainsKey(regionID)) diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs index 1505f875d2..77d87d43e9 100644 --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs @@ -524,10 +524,14 @@ namespace OpenSim.Data.PGSQL /// public double[,] LoadTerrain(UUID regionID) { + double[,] ret = null; TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); - return terrData.GetDoubles(); + if (terrData != null) + ret = terrData.GetDoubles(); + return ret; } + // Returns 'null' if region not found public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) { TerrainData terrData = null; diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index 5a34f094d3..9466e992e7 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -870,10 +870,14 @@ namespace OpenSim.Data.SQLite /// Heightfield data public double[,] LoadTerrain(UUID regionID) { + double[,] ret = null; TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); - return terrData.GetDoubles(); + if (terrData != null) + ret = terrData.GetDoubles(); + return ret; } + // Returns 'null' if region not found public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) { TerrainData terrData = null; diff --git a/OpenSim/Framework/TerrainData.cs b/OpenSim/Framework/TerrainData.cs index 1c52a6962e..9325df23d5 100644 --- a/OpenSim/Framework/TerrainData.cs +++ b/OpenSim/Framework/TerrainData.cs @@ -160,7 +160,11 @@ namespace OpenSim.Framework public override bool IsTaintedAt(int xx, int yy) { - return m_taint[xx / Constants.TerrainPatchSize, yy / Constants.TerrainPatchSize]; + int tx = xx / Constants.TerrainPatchSize; + int ty = yy / Constants.TerrainPatchSize; + bool ret = m_taint[tx, ty]; + m_taint[tx, ty] = false; + return ret; } // TerrainData.GetDatabaseBlob @@ -274,6 +278,7 @@ namespace OpenSim.Framework m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize]; // m_log.DebugFormat("{0} new by dimensions. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ); ClearTaint(); + ClearLand(0f); } public HeightmapTerrainData(short[] cmap, float pCompressionFactor, int pX, int pY, int pZ) : this(pX, pY, pZ) diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index bcf6af8849..54a6c0ce4b 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -1030,7 +1030,7 @@ namespace OpenSim.Framework finally { if (requestStream != null) - requestStream.Close(); + requestStream.Dispose(); // capture how much time was spent writing tickdata = Util.EnvironmentTickCountSubtract(tickstart); @@ -1183,7 +1183,7 @@ namespace OpenSim.Framework finally { if (requestStream != null) - requestStream.Close(); + requestStream.Dispose(); // capture how much time was spent writing tickdata = Util.EnvironmentTickCountSubtract(tickstart); @@ -1268,4 +1268,4 @@ namespace OpenSim.Framework return deserial; } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 1e36853d0c..77b94408d8 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -267,18 +267,20 @@ namespace OpenSim m_console.Commands.AddCommand("Archiving", false, "load oar", "load oar [--merge] [--skip-assets]" - + " [--forceterrain] [--forceparcels]" - + " [--rotation degrees] [--rotationCenter \"\"]" + + " [--force-terrain] [--force-parcels]" + + " [--no-objects]" + + " [--rotation degrees] [--rotation-center \"\"]" + " [--displacement \"\"]" + " []", "Load a region's data from an OAR archive.", "--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading)." + Environment.NewLine - + "--skip-assets will load the OAR but ignore the assets it contains." + Environment.NewLine - + "--displacement will add this value to the position of every object loaded" + Environment.NewLine - + "--forceterrain forces the loading of terrain from the oar (undoes suppression done by --merge)" + Environment.NewLine - + "--forceparcels forces the loading of parcels from the oar (undoes suppression done by --merge)" + Environment.NewLine - + "--rotation specified rotation to be applied to the oar. Specified in degrees." + Environment.NewLine - + "--rotationcenter Location (relative to original OAR) to apply rotation. Default is <128,128,0>" + Environment.NewLine + + "--skip-assets will load the OAR but ignore the assets it contains." + Environment.NewLine + + "--displacement will add this value to the position of every object loaded" + Environment.NewLine + + "--force-terrain forces the loading of terrain from the oar (undoes suppression done by --merge)" + Environment.NewLine + + "--force-parcels forces the loading of parcels from the oar (undoes suppression done by --merge)" + Environment.NewLine + + "--rotation specified rotation to be applied to the oar. Specified in degrees." + Environment.NewLine + + "--rotation-center Location (relative to original OAR) to apply rotation. Default is <128,128,0>" + Environment.NewLine + + "--no-objects suppresses the addition of any objects (good for loading only the terrain)" + Environment.NewLine + "The path can be either a filesystem location or a URI." + " If this is not given then the command looks for an OAR named region.oar in the current directory.", LoadOar); diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 7e50cc6da2..2da0a7461c 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -1290,9 +1290,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles webRequest.ContentType = "application/json-rpc"; webRequest.Method = "POST"; - Stream dataStream = webRequest.GetRequestStream(); - dataStream.Write(content, 0, content.Length); - dataStream.Close(); + using (Stream dataStream = webRequest.GetRequestStream()) + dataStream.Write(content, 0, content.Length); WebResponse webResponse = null; try @@ -1306,26 +1305,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles return false; } - Stream rstream = webResponse.GetResponseStream(); - - OSDMap mret = new OSDMap(); - try + using (webResponse) + using (Stream rstream = webResponse.GetResponseStream()) { - mret = (OSDMap)OSDParser.DeserializeJson(rstream); - } - catch (Exception e) - { - m_log.DebugFormat("[PROFILES]: JsonRpcRequest Error {0} - remote user with legacy profiles?", e.Message); - return false; - } + OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream); + if (mret.ContainsKey("error")) + return false; - if (mret.ContainsKey("error")) - return false; - - // get params... - OSD.DeserializeMembers(ref parameters, (OSDMap) mret["result"]); - return true; + // get params... + OSD.DeserializeMembers(ref parameters, (OSDMap)mret["result"]); + return true; + } } /// @@ -1366,9 +1357,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles webRequest.ContentType = "application/json-rpc"; webRequest.Method = "POST"; - Stream dataStream = webRequest.GetRequestStream(); - dataStream.Write(content, 0, content.Length); - dataStream.Close(); + using (Stream dataStream = webRequest.GetRequestStream()) + dataStream.Write(content, 0, content.Length); WebResponse webResponse = null; try @@ -1382,29 +1372,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles return false; } - Stream rstream = webResponse.GetResponseStream(); - - OSDMap response = new OSDMap(); - try + using (webResponse) + using (Stream rstream = webResponse.GetResponseStream()) { - response = (OSDMap)OSDParser.DeserializeJson(rstream); - } - catch (Exception e) - { - m_log.DebugFormat("[PROFILES]: JsonRpcRequest Error {0} - remote user with legacy profiles?", e.Message); - return false; - } + OSDMap response = new OSDMap(); + try + { + response = (OSDMap)OSDParser.DeserializeJson(rstream); + } + catch (Exception e) + { + m_log.DebugFormat("[PROFILES]: JsonRpcRequest Error {0} - remote user with legacy profiles?", e.Message); + return false; + } - if(response.ContainsKey("error")) - { - data = response["error"]; - return false; + if (response.ContainsKey("error")) + { + data = response["error"]; + return false; + } + + data = response; + + return true; } - - data = response; - - return true; } + #endregion Web Util } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index c3a8afdf93..a7237ea34a 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -488,9 +488,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest byte[] data = Util.UTF8.GetBytes(OutboundBody); Request.ContentLength = data.Length; - Stream bstream = Request.GetRequestStream(); - bstream.Write(data, 0, data.Length); - bstream.Close(); + using (Stream bstream = Request.GetRequestStream()) + bstream.Write(data, 0, data.Length); } try @@ -584,4 +583,4 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest Request.Abort(); } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index f4807addbb..0c4b79b948 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver protected Vector3 m_displacement = Vector3.Zero; /// - /// Rotation to apply to the objects as they are loaded. + /// Rotation (in radians) to apply to the objects as they are loaded. /// protected float m_rotation = 0f; @@ -130,6 +130,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// protected Vector3 m_rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f); + protected bool m_noObjects = false; + /// /// Used to cache lookups for valid uuids. /// @@ -177,14 +179,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_errorMessage = String.Empty; m_merge = options.ContainsKey("merge"); - m_forceTerrain = options.ContainsKey("forceTerrain"); - m_forceParcels = options.ContainsKey("forceParcels"); + m_forceTerrain = options.ContainsKey("force-terrain"); + m_forceParcels = options.ContainsKey("force-parcels"); + m_noObjects = options.ContainsKey("no-objects"); m_skipAssets = options.ContainsKey("skipAssets"); m_requestId = requestId; m_displacement = options.ContainsKey("displacement") ? (Vector3)options["displacement"] : Vector3.Zero; m_rotation = options.ContainsKey("rotation") ? (float)options["rotation"] : 0f; - m_rotationCenter = options.ContainsKey("rotationCenter") ? (Vector3)options["rotationCenter"] - : new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f); + m_rotationCenter = options.ContainsKey("rotation-center") ? (Vector3)options["rotation-center"] + : new Vector3(scene.RegionInfo.RegionSizeX / 2f, scene.RegionInfo.RegionSizeY / 2f, 0f); // Zero can never be a valid user id m_validUserUuids[UUID.Zero] = false; @@ -261,7 +264,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Process the file - if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) + if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH) && !m_noObjects) { sceneContext.SerialisedSceneObjects.Add(Encoding.UTF8.GetString(data)); } @@ -454,8 +457,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Reload serialized prims m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); - float angle = (float)(m_rotation / 180.0 * Math.PI); - OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, angle); + OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, m_rotation); UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject; @@ -483,16 +485,25 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Happily this does not do much to the object since it hasn't been added to the scene yet if (sceneObject.AttachmentPoint == 0) { - if (angle != 0f) + if (m_displacement != Vector3.Zero || m_rotation != 0f) { - sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation; - Vector3 offset = sceneObject.AbsolutePosition - m_rotationCenter; - offset *= rot; - sceneObject.AbsolutePosition = m_rotationCenter + offset; - } - if (m_displacement != Vector3.Zero) - { - sceneObject.AbsolutePosition += m_displacement; + Vector3 pos = sceneObject.AbsolutePosition; + if (m_rotation != 0f) + { + // Rotate the object + sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation; + // Get object position relative to rotation axis + Vector3 offset = pos - m_rotationCenter; + // Rotate the object position + offset *= rot; + // Restore the object position back to relative to the region + pos = m_rotationCenter + offset; + } + if (m_displacement != Vector3.Zero) + { + pos += m_displacement; + } + sceneObject.AbsolutePosition = pos; } } @@ -868,10 +879,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver ITerrainModule terrainModule = scene.RequestModuleInterface(); MemoryStream ms = new MemoryStream(data); - if (m_displacement != Vector3.Zero) + if (m_displacement != Vector3.Zero || m_rotation != 0f) { - Vector2 terrainDisplacement = new Vector2(m_displacement.X, m_displacement.Y); - terrainModule.LoadFromStream(terrainPath, terrainDisplacement, ms); + Vector2 rotationCenter = new Vector2(m_rotationCenter.X, m_rotationCenter.Y); + terrainModule.LoadFromStream(terrainPath, m_displacement, m_rotation, rotationCenter, ms); } else { diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index 2a6f1eb23b..2b2da6f2de 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs @@ -106,6 +106,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver bool skipAssets = false; bool forceTerrain = false; bool forceParcels = false; + bool noObjects = false; Vector3 displacement = new Vector3(0f, 0f, 0f); float rotation = 0f; Vector3 rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0); @@ -113,26 +114,48 @@ namespace OpenSim.Region.CoreModules.World.Archiver OptionSet options = new OptionSet(); options.Add("m|merge", delegate (string v) { mergeOar = (v != null); }); options.Add("s|skip-assets", delegate (string v) { skipAssets = (v != null); }); - options.Add("forceterrain", delegate (string v) { forceTerrain = (v != null); }); - options.Add("forceparcels", delegate (string v) { forceParcels = (v != null); }); + options.Add("force-terrain", delegate (string v) { forceTerrain = (v != null); }); + options.Add("forceterrain", delegate (string v) { forceTerrain = (v != null); }); // downward compatibility + options.Add("force-parcels", delegate (string v) { forceParcels = (v != null); }); + options.Add("forceparcels", delegate (string v) { forceParcels = (v != null); }); // downward compatibility + options.Add("no-objects", delegate (string v) { noObjects = (v != null); }); options.Add("displacement=", delegate (string v) { try { displacement = v == null ? Vector3.Zero : Vector3.Parse(v); } - catch (Exception e) + catch { m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing displacement"); - displacement = new Vector3(0f, 0f, 0f); + m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as vector3: --displacement \"<128,128,0>\""); + return; } }); options.Add("rotation=", delegate (string v) { - rotation = float.Parse(v); - rotation = Util.Clamp(rotation, -359f, 359f); + try + { + rotation = v == null ? 0f : float.Parse(v); + } + catch + { + m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing rotation"); + m_log.ErrorFormat("[ARCHIVER MODULE] Must be an angle in degrees between -360 and +360: --rotation 45"); + return; + } + // Convert to radians for internals + rotation = Util.Clamp(rotation, -359f, 359f) / 180f * (float)Math.PI; }); - options.Add("rotationcenter=", delegate (string v) { - // RA 20130119: libomv's Vector2.Parse doesn't work. Need to use vector3 for the moment - rotationCenter = Vector3.Parse(v); + options.Add("rotation-center=", delegate (string v) { + try + { + rotationCenter = v == null ? Vector3.Zero : Vector3.Parse(v); + } + catch + { + m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing rotation displacement"); + m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as vector3: --rotation-center \"<128,128,0>\""); + return; + } }); // Send a message to the region ready module @@ -155,11 +178,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver Dictionary archiveOptions = new Dictionary(); if (mergeOar) archiveOptions.Add("merge", null); if (skipAssets) archiveOptions.Add("skipAssets", null); - if (forceTerrain) archiveOptions.Add("forceTerrain", null); - if (forceParcels) archiveOptions.Add("forceParcels", null); + if (forceTerrain) archiveOptions.Add("force-terrain", null); + if (forceParcels) archiveOptions.Add("force-parcels", null); + if (noObjects) archiveOptions.Add("no-objects", null); archiveOptions.Add("displacement", displacement); archiveOptions.Add("rotation", rotation); - archiveOptions.Add("rotationCenter", rotationCenter); + archiveOptions.Add("rotation-center", rotationCenter); if (mainParams.Count > 2) { diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 53f41f986e..e08a42da9d 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -579,7 +579,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests ArchiveConstants.CONTROL_FILE_PATH, new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup())); - LandObject lo = new LandObject(groupID, true, null); + LandObject lo = new LandObject(groupID, true, m_scene); lo.SetLandBitmap(lo.BasicFullRegionLandBitmap()); LandData ld = lo.LandData; ld.GlobalID = landID; diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index f8f498647d..939512fcc2 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -134,7 +134,10 @@ namespace OpenSim.Region.CoreModules.World.Land public LandObject(UUID owner_id, bool is_group_owned, Scene scene) { m_scene = scene; - m_landBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; + if (m_scene == null) + m_landBitmap = new bool[Constants.RegionSize / landUnit, Constants.RegionSize / landUnit]; + else + m_landBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; LandData.OwnerID = owner_id; if (is_group_owned) diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs index 6f344c8625..561552a6bd 100644 --- a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs +++ b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs @@ -68,9 +68,6 @@ namespace OpenSim.Region.CoreModules // updating those region settings in GenSunPos() private bool receivedEstateToolsSunUpdate = false; - // Configurable values - private string m_RegionMode = "SL"; - // Sun's position information is updated and sent to clients every m_UpdateInterval frames private int m_UpdateInterval = 0; @@ -90,7 +87,6 @@ namespace OpenSim.Region.CoreModules // private double m_longitude = 0; // private double m_latitude = 0; // Configurable defaults Defaults close to SL - private string d_mode = "SL"; private int d_frame_mod = 100; // Every 10 seconds (actually less) private double d_day_length = 4; // A VW day is 4 RW hours long private int d_year_length = 60; // There are 60 VW days in a VW year @@ -134,12 +130,15 @@ namespace OpenSim.Region.CoreModules private const int TICKS_PER_SECOND = 10000000; + private ulong m_CurrentTimeOffset = 0; + // Current time in elapsed seconds since Jan 1st 1970 private ulong CurrentTime { get { - return (ulong)(((DateTime.Now.Ticks) - TicksToEpoch + TicksUTCOffset) / TICKS_PER_SECOND); + ulong ctime = (ulong)(((DateTime.Now.Ticks) - TicksToEpoch + TicksUTCOffset) / TICKS_PER_SECOND); + return ctime + m_CurrentTimeOffset; } } @@ -262,10 +261,8 @@ namespace OpenSim.Region.CoreModules private float GetCurrentTimeAsLindenSunHour() { - if (m_SunFixed) - return m_SunFixedHour + 6; - - return GetCurrentSunHour() + 6.0f; + float curtime = m_SunFixed ? m_SunFixedHour : GetCurrentSunHour(); + return (curtime + 6.0f) % 24.0f; } #region INonSharedRegion Methods @@ -290,8 +287,6 @@ namespace OpenSim.Region.CoreModules // Just in case they don't have the stanzas try { - // Mode: determines how the sun is handled - m_RegionMode = config.Configs["Sun"].GetString("mode", d_mode); // Mode: determines how the sun is handled // m_latitude = config.Configs["Sun"].GetDouble("latitude", d_latitude); // Mode: determines how the sun is handled @@ -314,7 +309,6 @@ namespace OpenSim.Region.CoreModules catch (Exception e) { m_log.Debug("[SUN]: Configuration access failed, using defaults. Reason: " + e.Message); - m_RegionMode = d_mode; m_YearLengthDays = d_year_length; m_DayLengthHours = d_day_length; m_HorizonShift = d_day_night; @@ -325,40 +319,28 @@ namespace OpenSim.Region.CoreModules // m_longitude = d_longitude; } - switch (m_RegionMode) - { - case "T1": - default: - case "SL": - // Time taken to complete a cycle (day and season) + SecondsPerSunCycle = (uint) (m_DayLengthHours * 60 * 60); + SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays); - SecondsPerSunCycle = (uint) (m_DayLengthHours * 60 * 60); - SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays); + // Ration of real-to-virtual time - // Ration of real-to-virtual time + // VWTimeRatio = 24/m_day_length; - // VWTimeRatio = 24/m_day_length; + // Speed of rotation needed to complete a cycle in the + // designated period (day and season) - // Speed of rotation needed to complete a cycle in the - // designated period (day and season) + SunSpeed = m_SunCycle/SecondsPerSunCycle; + SeasonSpeed = m_SeasonalCycle/SecondsPerYear; - SunSpeed = m_SunCycle/SecondsPerSunCycle; - SeasonSpeed = m_SeasonalCycle/SecondsPerYear; + // Horizon translation - // Horizon translation - - HorizonShift = m_HorizonShift; // Z axis translation - // HoursToRadians = (SunCycle/24)*VWTimeRatio; - - m_log.Debug("[SUN]: Mode is " + m_RegionMode); - m_log.Debug("[SUN]: Initialization completed. Day is " + SecondsPerSunCycle + " seconds, and year is " + m_YearLengthDays + " days"); - m_log.Debug("[SUN]: Axis offset is " + m_HorizonShift); - m_log.Debug("[SUN]: Percentage of time for daylight " + m_DayTimeSunHourScale); - m_log.Debug("[SUN]: Positional data updated every " + m_UpdateInterval + " frames"); - - break; - } + HorizonShift = m_HorizonShift; // Z axis translation + // HoursToRadians = (SunCycle/24)*VWTimeRatio; + m_log.Debug("[SUN]: Initialization completed. Day is " + SecondsPerSunCycle + " seconds, and year is " + m_YearLengthDays + " days"); + m_log.Debug("[SUN]: Axis offset is " + m_HorizonShift); + m_log.Debug("[SUN]: Percentage of time for daylight " + m_DayTimeSunHourScale); + m_log.Debug("[SUN]: Positional data updated every " + m_UpdateInterval + " frames"); } public Type ReplaceableInterface @@ -385,7 +367,8 @@ namespace OpenSim.Region.CoreModules string sunCommand = string.Format("sun {0}", kvp.Key); m_scene.AddCommand("Regions", this, sunCommand, string.Format("{0} []", sunCommand), kvp.Value, "", HandleSunConsoleCommand); } - + m_scene.AddCommand("Regions", this, "sun help", "sun help", "list parameters that can be changed", "", HandleSunConsoleCommand); + m_scene.AddCommand("Regions", this, "sun list", "sun list", "list parameters that can be changed", "", HandleSunConsoleCommand); ready = true; } @@ -419,23 +402,22 @@ namespace OpenSim.Region.CoreModules public void SunToClient(IClientAPI client) { - if (m_RegionMode != "T1") + if (ready) { - if (ready) + if (m_SunFixed) { - if (m_SunFixed) - { - // m_log.DebugFormat("[SUN]: SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ", m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString()); - client.SendSunPos(Position, Velocity, PosTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); - } - else - { - // m_log.DebugFormat("[SUN]: SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ", m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString()); - client.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); - } + // m_log.DebugFormat("[SUN]: Fixed SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ", + // m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString()); + client.SendSunPos(Position, Velocity, PosTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); + } + else + { + // m_log.DebugFormat("[SUN]: SunHour {0}, Position {1}, PosTime {2}, OrbitalPosition : {3} ", + // m_SunFixedHour, Position.ToString(), PosTime.ToString(), OrbitalPosition.ToString()); + client.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition); } } - } + } public void SunUpdate() { @@ -532,6 +514,9 @@ namespace OpenSim.Region.CoreModules case "update_interval": return m_UpdateInterval; + case "current_time": + return GetCurrentTimeAsLindenSunHour(); + default: throw new Exception("Unknown sun parameter."); } @@ -539,7 +524,51 @@ namespace OpenSim.Region.CoreModules public void SetSunParameter(string param, double value) { - HandleSunConsoleCommand("sun", new string[] {param, value.ToString() }); + switch (param) + { + case "year_length": + m_YearLengthDays = (int)value; + SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays); + SeasonSpeed = m_SeasonalCycle/SecondsPerYear; + break; + + case "day_length": + m_DayLengthHours = value; + SecondsPerSunCycle = (uint) (m_DayLengthHours * 60 * 60); + SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays); + SunSpeed = m_SunCycle/SecondsPerSunCycle; + SeasonSpeed = m_SeasonalCycle/SecondsPerYear; + break; + + case "day_night_offset": + m_HorizonShift = value; + HorizonShift = m_HorizonShift; + break; + + case "day_time_sun_hour_scale": + m_DayTimeSunHourScale = value; + break; + + case "update_interval": + m_UpdateInterval = (int)value; + break; + + case "current_time": + value = (value + 18.0) % 24.0; + // set the current offset so that the effective sun time is the parameter + m_CurrentTimeOffset = 0; // clear this first so we use raw time + m_CurrentTimeOffset = (ulong)(SecondsPerSunCycle * value/ 24.0) - (CurrentTime % SecondsPerSunCycle); + break; + + default: + throw new Exception("Unknown sun parameter."); + + // Generate shared values + GenSunPos(); + + // When sun settings are updated, we should update all clients with new settings. + SunUpdateToAllClients(); + } } public float GetCurrentSunHour() @@ -572,7 +601,7 @@ namespace OpenSim.Region.CoreModules foreach (string output in ParseCmdParams(cmdparams)) { - m_log.Info("[SUN] " + output); + MainConsole.Instance.Output(output); } } @@ -581,10 +610,11 @@ namespace OpenSim.Region.CoreModules Dictionary Params = new Dictionary(); Params.Add("year_length", "number of days to a year"); - Params.Add("day_length", "number of seconds to a day"); + Params.Add("day_length", "number of hours to a day"); Params.Add("day_night_offset", "induces a horizon shift"); Params.Add("update_interval", "how often to update the sun's position in frames"); Params.Add("day_time_sun_hour_scale", "scales day light vs nite hours to change day/night ratio"); + Params.Add("current_time", "time in seconds of the simulator"); return Params; } @@ -618,46 +648,15 @@ namespace OpenSim.Region.CoreModules } else if (args.Length == 3) { - float value = 0.0f; - if (!float.TryParse(args[2], out value)) + double value = 0.0; + if (! double.TryParse(args[2], out value)) { Output.Add(String.Format("The parameter value {0} is not a valid number.", args[2])); + return Output; } - switch (args[1].ToLower()) - { - case "year_length": - m_YearLengthDays = (int)value; - break; - - case "day_length": - m_DayLengthHours = value; - break; - - case "day_night_offset": - m_HorizonShift = value; - break; - - case "day_time_sun_hour_scale": - m_DayTimeSunHourScale = value; - break; - - case "update_interval": - m_UpdateInterval = (int)value; - break; - - default: - Output.Add(String.Format("Unknown parameter {0}.", args[1])); - return Output; - } - + SetSunParameter(args[1].ToLower(), value); Output.Add(String.Format("Parameter {0} set to {1}.", args[1], value.ToString())); - - // Generate shared values - GenSunPos(); - - // When sun settings are updated, we should update all clients with new settings. - SunUpdateToAllClients(); } return Output; diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 7bc5e8845a..08891d98a8 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -316,8 +316,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain public void LoadFromStream(string filename, Stream stream) { - Vector2 defaultDisplacement = new Vector2(0f, 0f); - LoadFromStream(filename, defaultDisplacement, stream); + LoadFromStream(filename, Vector3.Zero, 0f, Vector2.Zero, stream); } /// @@ -325,7 +324,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain /// /// Filename to terrain file. Type is determined by extension. /// - public void LoadFromStream(string filename, Vector2 displacement, Stream stream) + public void LoadFromStream(string filename, Vector3 displacement, + float radianRotation, Vector2 rotationDisplacement, Stream stream) { foreach (KeyValuePair loader in m_loaders) { @@ -336,7 +336,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain try { ITerrainChannel channel = loader.Value.LoadStream(stream); - MergeTerrainIntoExisting(channel, displacement); + m_channel.Merge(channel, displacement, radianRotation, rotationDisplacement); UpdateRevertMap(); } catch (NotImplementedException) @@ -356,33 +356,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename)); } - private void MergeTerrainIntoExisting(ITerrainChannel channel, Vector2 displacement) - { - if (displacement == Vector2.Zero) - { - // If there is no displacement, just use this channel as the new heightmap - m_scene.Heightmap = channel; - m_channel = channel; - } - else - { - // If there is a displacement, we copy the loaded heightmap into the overall region - for (int xx = 0; xx < channel.Width; xx++) - { - for (int yy = 0; yy < channel.Height; yy++) - { - int dispX = xx + (int)displacement.X; - int dispY = yy + (int)displacement.Y; - if (dispX >= 0 && dispX < m_channel.Width - && dispY >= 0 && dispY < m_channel.Height) - { - m_channel[dispX, dispY] = channel[xx, yy]; - } - } - } - } - } - private static Stream URIFetch(Uri uri) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); diff --git a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs index be719ea2d3..96c16a9a8e 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs @@ -40,10 +40,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests [Test] public void BrushTest() { + int midRegion = (int)Constants.RegionSize / 2; + + // Create a mask that covers only the left half of the region bool[,] allowMask = new bool[(int)Constants.RegionSize, 256]; int x; int y; - for (x = 0; x < (int)((int)Constants.RegionSize * 0.5f); x++) + for (x = 0; x < midRegion; x++) { for (y = 0; y < (int)Constants.RegionSize; y++) { @@ -57,13 +60,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests TerrainChannel map = new TerrainChannel((int)Constants.RegionSize, (int)Constants.RegionSize); ITerrainPaintableEffect effect = new RaiseSphere(); - effect.PaintEffect(map, allowMask, (int)Constants.RegionSize * 0.5f, (int)Constants.RegionSize * 0.5f, -1.0, 2, 0.1); - Assert.That(map[127, (int)((int)Constants.RegionSize * 0.5f)] > 0.0, "Raise brush should raising value at this point (127,128)."); - Assert.That(map[124, (int)((int)Constants.RegionSize * 0.5f)] > 0.0, "Raise brush should raising value at this point (124,128)."); - Assert.That(map[123, (int)((int)Constants.RegionSize * 0.5f)] == 0.0, "Raise brush should not change value at this point (123,128)."); - Assert.That(map[128, (int)((int)Constants.RegionSize * 0.5f)] == 0.0, "Raise brush should not change value at this point (128,128)."); - Assert.That(map[0, (int)((int)Constants.RegionSize * 0.5f)] == 0.0, "Raise brush should not change value at this point (0,128)."); - + effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0); + Assert.That(map[127, midRegion] > 0.0, "Raise brush should raising value at this point (127,128)."); + Assert.That(map[125, midRegion] > 0.0, "Raise brush should raising value at this point (124,128)."); + Assert.That(map[120, midRegion] == 0.0, "Raise brush should not change value at this point (120,128)."); + Assert.That(map[128, midRegion] == 0.0, "Raise brush should not change value at this point (128,128)."); + Assert.That(map[0, midRegion] == 0.0, "Raise brush should not change value at this point (0,128)."); // // Test LowerSphere // @@ -77,13 +79,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests } effect = new LowerSphere(); - effect.PaintEffect(map, allowMask, ((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), -1.0, 2, 6.0); - Assert.That(map[127, (int)((int)Constants.RegionSize * 0.5f)] >= 0.0, "Lower should not lowering value below 0.0 at this point (127,128)."); - Assert.That(map[127, (int)((int)Constants.RegionSize * 0.5f)] == 0.0, "Lower brush should lowering value to 0.0 at this point (127,128)."); - Assert.That(map[124, (int)((int)Constants.RegionSize * 0.5f)] < 1.0, "Lower brush should lowering value at this point (124,128)."); - Assert.That(map[123, (int)((int)Constants.RegionSize * 0.5f)] == 1.0, "Lower brush should not change value at this point (123,128)."); - Assert.That(map[128, (int)((int)Constants.RegionSize * 0.5f)] == 1.0, "Lower brush should not change value at this point (128,128)."); - Assert.That(map[0, (int)((int)Constants.RegionSize * 0.5f)] == 1.0, "Lower brush should not change value at this point (0,128)."); + effect.PaintEffect(map, allowMask, midRegion, midRegion, -1.0, 2, 6.0); + Assert.That(map[127, midRegion] >= 0.0, "Lower should not lowering value below 0.0 at this point (127,128)."); + Assert.That(map[127, midRegion] == 0.0, "Lower brush should lowering value to 0.0 at this point (127,128)."); + Assert.That(map[125, midRegion] < 1.0, "Lower brush should lowering value at this point (124,128)."); + Assert.That(map[120, midRegion] == 1.0, "Lower brush should not change value at this point (120,128)."); + Assert.That(map[128, midRegion] == 1.0, "Lower brush should not change value at this point (128,128)."); + Assert.That(map[0, midRegion] == 1.0, "Lower brush should not change value at this point (0,128)."); } [Test] @@ -100,10 +102,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain.Tests x[0, 0] -= 1.0; Assert.That(x[0, 0] == 4.0, "Terrain addition/subtraction error."); - x[0, 0] = Math.PI; - double[,] doublesExport = x.GetDoubles(); - Assert.That(doublesExport[0, 0] == Math.PI, "Export to double[,] array not working correctly."); - x[0, 0] = 1.0; float[] floatsExport = x.GetFloatsSerialised(); Assert.That(floatsExport[0] == 1.0f, "Export to float[] not working correctly."); diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index f57be83b71..a3b0f39498 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -899,7 +899,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap finally { if (os != null) - os.Close(); + os.Dispose(); } string response_mapItems_reply = null; diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index 9817cf71b9..d5dcdddf6a 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -71,6 +71,32 @@ namespace OpenSim.Region.Framework.Interfaces UUID owner, bool senseAsAgent, Scene scene, AvatarAppearance appearance); + /// + /// Create an NPC with a user-supplied agentID + /// + /// + /// + /// + /// + /// The desired agent ID + /// + /// + /// Make the NPC show up as an agent on LSL sensors. The default is + /// that they show up as the NPC type instead, but this is currently + /// an OpenSim-only extension. + /// + /// + /// + /// The avatar appearance to use for the new NPC. + /// + /// + /// The UUID of the ScenePresence created. UUID.Zero if there was a + /// failure. + /// + UUID CreateNPC(string firstname, string lastname, + Vector3 position, UUID agentID, UUID owner, bool senseAsAgent, Scene scene, + AvatarAppearance appearance); + /// /// Check if the agent is an NPC. /// diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs index 469bd31506..f660b8dbe0 100644 --- a/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs +++ b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs @@ -26,6 +26,7 @@ */ using OpenSim.Framework; +using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { @@ -56,5 +57,7 @@ namespace OpenSim.Region.Framework.Interfaces ITerrainChannel MakeCopy(); string SaveToXmlString(); void LoadFromXmlString(string data); + // Merge some terrain into this channel + void Merge(ITerrainChannel newTerrain, Vector3 displacement, float radianRotation, Vector2 rotationDisplacement); } } diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs index 189a30accb..a6f5d9838e 100644 --- a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// void LoadFromStream(string filename, Stream stream); - void LoadFromStream(string filename, Vector2 displacement, Stream stream); + void LoadFromStream(string filename, Vector3 displacement, float radianRotation, Vector2 rotationDisplacement, Stream stream); void LoadFromStream(string filename, System.Uri pathToTerrainHeightmap); /// /// Save a terrain to a stream. diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs index b4b1823de3..24709dcf74 100644 --- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs +++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs @@ -36,6 +36,8 @@ using OpenSim.Data; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; +using OpenMetaverse; + using log4net; namespace OpenSim.Region.Framework.Scenes @@ -212,6 +214,76 @@ namespace OpenSim.Region.Framework.Scenes sr.Close(); } + // ITerrainChannel.Merge + public void Merge(ITerrainChannel newTerrain, Vector3 displacement, float radianRotation, Vector2 rotationDisplacement) + { + for (int xx = 0; xx < newTerrain.Width; xx++) + { + for (int yy = 0; yy < newTerrain.Height; yy++) + { + int dispX = (int)displacement.X; + int dispY = (int)displacement.Y; + float newHeight = (float)newTerrain[xx, yy] + displacement.Z; + if (radianRotation == 0) + { + // If no rotation, place the new height in the specified location + dispX += xx; + dispY += yy; + if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY) + { + m_terrainData[dispX, dispY] = newHeight; + } + } + else + { + // If rotating, we have to smooth the result because the conversion + // to ints will mean heightmap entries will not get changed + // First compute the rotation location for the new height. + dispX += (int)(rotationDisplacement.X + + ((float)xx - rotationDisplacement.X) * Math.Cos(radianRotation) + - ((float)yy - rotationDisplacement.Y) * Math.Sin(radianRotation) ); + + dispY += (int)(rotationDisplacement.Y + + ((float)xx - rotationDisplacement.X) * Math.Sin(radianRotation) + + ((float)yy - rotationDisplacement.Y) * Math.Cos(radianRotation) ); + + if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY) + { + float oldHeight = m_terrainData[dispX, dispY]; + // Smooth the heights around this location if the old height is far from this one + for (int sxx = dispX - 2; sxx < dispX + 2; sxx++) + { + for (int syy = dispY - 2; syy < dispY + 2; syy++) + { + if (sxx >= 0 && sxx < m_terrainData.SizeX && syy >= 0 && syy < m_terrainData.SizeY) + { + if (sxx == dispX && syy == dispY) + { + // Set height for the exact rotated point + m_terrainData[dispX, dispY] = newHeight; + } + else + { + if (Math.Abs(m_terrainData[sxx, syy] - newHeight) > 1f) + { + // If the adjacent height is far off, force it to this height + m_terrainData[sxx, syy] = newHeight; + } + } + } + } + } + } + + if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY) + { + m_terrainData[dispX, dispY] = (float)newTerrain[xx, yy]; + } + } + } + } + } + #endregion public TerrainChannel Copy() diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index 75a51b5e68..fe6cb84711 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs @@ -161,7 +161,7 @@ namespace OpenSim.Region.Framework.Scenes { // Get the prim's default texture. This will be used for faces which don't have their own texture if (textureEntry.DefaultTexture != null) - assetUuids[textureEntry.DefaultTexture.TextureID] = (sbyte)AssetType.Texture; + GatherTextureEntryAssets(textureEntry.DefaultTexture, assetUuids); if (textureEntry.FaceTextures != null) { @@ -169,7 +169,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures) { if (texture != null) - assetUuids[texture.TextureID] = (sbyte)AssetType.Texture; + GatherTextureEntryAssets(texture, assetUuids); } } } @@ -233,6 +233,19 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Gather all the asset uuids found in one face of a Texture Entry. + /// + private void GatherTextureEntryAssets(Primitive.TextureEntryFace texture, IDictionary assetUuids) + { + assetUuids[texture.TextureID] = (sbyte)AssetType.Texture; + + if (texture.MaterialID != UUID.Zero) + { + GatherAssetUuids(texture.MaterialID, (sbyte)OpenSimAssetType.Material, assetUuids); + } + } + // /// // /// The callback made when we request the asset for an object from the asset service. // /// diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index 296ab87274..d059b97516 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -304,7 +304,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady finally { if (os != null) - os.Close(); + os.Dispose(); } } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index a895ee197a..fb644b7163 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC private readonly string m_firstname; private readonly string m_lastname; private readonly Vector3 m_startPos; - private readonly UUID m_uuid = UUID.Random(); + private readonly UUID m_uuid; private readonly Scene m_scene; private readonly UUID m_ownerID; @@ -71,6 +71,19 @@ namespace OpenSim.Region.OptionalModules.World.NPC m_firstname = firstname; m_lastname = lastname; m_startPos = position; + m_uuid = UUID.Random(); + m_scene = scene; + m_ownerID = ownerID; + SenseAsAgent = senseAsAgent; + } + + public NPCAvatar( + string firstname, string lastname, UUID agentID, Vector3 position, UUID ownerID, bool senseAsAgent, Scene scene) + { + m_firstname = firstname; + m_lastname = lastname; + m_startPos = position; + m_uuid = agentID; m_scene = scene; m_ownerID = ownerID; SenseAsAgent = senseAsAgent; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index fffe1ab703..8a2da6e883 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -140,8 +140,30 @@ namespace OpenSim.Region.OptionalModules.World.NPC Vector3 position, UUID owner, bool senseAsAgent, Scene scene, AvatarAppearance appearance) { - NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, - owner, senseAsAgent, scene); + return CreateNPC(firstname, lastname, position, UUID.Zero, owner, senseAsAgent, scene, appearance); + } + + public UUID CreateNPC(string firstname, string lastname, + Vector3 position, UUID agentID, UUID owner, bool senseAsAgent, Scene scene, + AvatarAppearance appearance) + { + NPCAvatar npcAvatar = null; + + try + { + if (agentID == UUID.Zero) + npcAvatar = new NPCAvatar(firstname, lastname, position, + owner, senseAsAgent, scene); + else + npcAvatar = new NPCAvatar(firstname, lastname, agentID, position, + owner, senseAsAgent, scene); + } + catch (Exception e) + { + m_log.Info("[NPC MODULE]: exception creating NPC avatar: " + e.ToString()); + return UUID.Zero; + } + npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 834228e992..d993e6a070 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -538,7 +538,7 @@ public static class BSParam (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ), new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", - (float)BSTerrainPhys.TerrainImplementation.Mesh ), + (float)BSTerrainPhys.TerrainImplementation.Heightmap ), new ParameterDefn("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , 2 ), new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index fe014fcafe..2d2e55f34c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -235,6 +235,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Set default values for physics parameters plus any overrides from the ini file GetInitialParameterValues(config); + // Force some parameters to values depending on other configurations + // Only use heightmap terrain implementation if terrain larger than legacy size + if ((uint)regionExtent.X > Constants.RegionSize || (uint)regionExtent.Y > Constants.RegionSize) + { + m_log.WarnFormat("{0} Forcing terrain implementation to heightmap for large region", LogHeader); + BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; + } + // Get the connection to the physics engine (could be native or one of many DLLs) PE = SelectUnderlyingBulletEngine(BulletEngineName); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 7b56abf723..91885b7f6d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -101,7 +101,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// protected TaskInventoryItem m_item; - protected bool throwErrorOnNotImplemented = true; + protected bool throwErrorOnNotImplemented = false; protected AsyncCommandManager AsyncCommands = null; protected float m_ScriptDelayFactor = 1.0f; protected float m_ScriptDistanceFactor = 1.0f; @@ -261,7 +261,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((item = GetScriptByName(name)) != UUID.Zero) m_ScriptEngine.ResetScript(item); else - ShoutError("llResetOtherScript: script "+name+" not found"); + Error("llResetOtherScript", "Can't find script '" + name + "'"); } public LSL_Integer llGetScriptState(string name) @@ -275,7 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return m_ScriptEngine.GetScriptState(item) ?1:0; } - ShoutError("llGetScriptState: script "+name+" not found"); + Error("llGetScriptState", "Can't find script '" + name + "'"); // If we didn't find it, then it's safe to // assume it is not running. @@ -298,7 +298,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - ShoutError("llSetScriptState: script "+name+" not found"); + Error("llSetScriptState", "Can't find script '" + name + "'"); } } @@ -890,7 +890,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (channelID == 0) { - LSLError("Cannot use llRegionSay() on channel 0"); + Error("llRegionSay", "Cannot use on channel 0"); return; } @@ -2553,9 +2553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSound(string sound, double volume, int queue, int loop) { m_host.AddScriptLPS(1); - // This function has been deprecated - // see http://www.lslwiki.net/lslwiki/wakka.php?wakka=llSound - Deprecated("llSound"); + Deprecated("llSound", "Use llPlaySound instead"); } // Xantor 20080528 PlaySound updated so it accepts an objectinventory name -or- a key to a sound @@ -2886,7 +2884,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) { - LSLError("No permissions to give money"); + Error("llGiveMoney", "No permissions to give money"); return; } @@ -2894,7 +2892,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(destination, out toID)) { - LSLError("Bad key in llGiveMoney"); + Error("llGiveMoney", "Bad key in llGiveMoney"); return; } @@ -2914,28 +2912,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) { m_host.AddScriptLPS(1); - Deprecated("llMakeExplosion"); + Deprecated("llMakeExplosion", "Use llParticleSystem instead"); ScriptSleep(100); } public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset) { m_host.AddScriptLPS(1); - Deprecated("llMakeFountain"); + Deprecated("llMakeFountain", "Use llParticleSystem instead"); ScriptSleep(100); } public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) { m_host.AddScriptLPS(1); - Deprecated("llMakeSmoke"); + Deprecated("llMakeSmoke", "Use llParticleSystem instead"); ScriptSleep(100); } public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) { m_host.AddScriptLPS(1); - Deprecated("llMakeFire"); + Deprecated("llMakeFire", "Use llParticleSystem instead"); ScriptSleep(100); } @@ -2957,13 +2955,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (item == null) { - llSay(0, "Could not find object " + inventory); + Error("llRezAtRoot", "Can't find object '" + inventory + "'"); return; } if (item.InvType != (int)InventoryType.Object) { - llSay(0, "Unable to create requested object. Object is missing from database."); + Error("llRezAtRoot", "Can't create requested object; object is missing from database"); return; } @@ -3053,7 +3051,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llStopLookAt() { m_host.AddScriptLPS(1); -// NotImplemented("llStopLookAt"); m_host.StopLookAt(); } @@ -3237,13 +3234,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llTakeCamera(string avatar) { m_host.AddScriptLPS(1); - Deprecated("llTakeCamera"); + Deprecated("llTakeCamera", "Use llSetCameraParams instead"); } public void llReleaseCamera(string avatar) { m_host.AddScriptLPS(1); - Deprecated("llReleaseCamera"); + Deprecated("llReleaseCamera", "Use llClearCameraParams instead"); } public LSL_String llGetOwner() @@ -3320,7 +3317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface(); if (emailModule == null) { - ShoutError("llEmail: email module not configured"); + Error("llEmail", "Email module not configured"); return; } @@ -3334,7 +3331,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface(); if (emailModule == null) { - ShoutError("llGetNextEmail: email module not configured"); + Error("llGetNextEmail", "Email module not configured"); return; } Email email; @@ -3419,17 +3416,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api catch (NotImplementedException) { // Currently not implemented in DotNetEngine only XEngine - NotImplemented("llMinEventDelay in DotNetEngine"); + NotImplemented("llMinEventDelay", "In DotNetEngine"); } } - /// - /// llSoundPreload is deprecated. In SL this appears to do absolutely nothing - /// and is documented to have no delay. - /// public void llSoundPreload(string sound) { m_host.AddScriptLPS(1); + Deprecated("llSoundPreload", "Use llPreloadSound instead"); } public void llRotLookAt(LSL_Rotation target, double strength, double damping) @@ -3734,7 +3728,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { - ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); + Error("llCreateLink", "PERMISSION_CHANGE_LINKS permission not set"); return; } @@ -3789,7 +3783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { - ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); + Error("llBreakLink", "PERMISSION_CHANGE_LINKS permission not set"); return; } @@ -4009,7 +4003,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(destination, out destId)) { - llSay(0, "Could not parse key " + destination); + Error("llGiveInventory", "Can't parse destination key '" + destination + "'"); return; } @@ -4017,8 +4011,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (item == null) { - llSay(0, String.Format("Could not find object '{0}'", inventory)); - throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); + Error("llGiveInventory", "Can't find inventory object '" + inventory + "'"); } UUID objId = item.ItemID; @@ -4042,7 +4035,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (account == null) { - llSay(0, "Can't find destination "+destId.ToString()); + Error("llGiveInventory", "Can't find destination '" + destId.ToString() + "'"); return; } } @@ -4394,17 +4387,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID av = new UUID(); if (!UUID.TryParse(agent,out av)) { - LSLError("First parameter to llTextBox needs to be a key"); + Error("llTextBox", "First parameter must be a key"); return; } if (message == string.Empty) { - ShoutError("Trying to use llTextBox with empty message."); + Error("llTextBox", "Empty message"); } else if (message.Length > 512) { - ShoutError("Trying to use llTextBox with message over 512 characters."); + Error("llTextBox", "Message more than 512 characters"); } else { @@ -6814,17 +6807,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID av = new UUID(); if (!UUID.TryParse(avatar,out av)) { - LSLError("First parameter to llDialog needs to be a key"); + Error("llDialog", "First parameter must be a key"); return; } if (buttons.Length < 1) { - LSLError("No less than 1 button can be shown"); + Error("llDialog", "At least 1 button must be shown"); return; } if (buttons.Length > 12) { - LSLError("No more than 12 buttons can be shown"); + Error("llDialog", "No more than 12 buttons can be shown"); return; } string[] buts = new string[buttons.Length]; @@ -6832,12 +6825,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (buttons.Data[i].ToString() == String.Empty) { - LSLError("button label cannot be blank"); + Error("llDialog", "Button label cannot be blank"); return; } if (buttons.Data[i].ToString().Length > 24) { - LSLError("button label cannot be longer than 24 characters"); + Error("llDialog", "Button label cannot be longer than 24 characters"); return; } buts[i] = buttons.Data[i].ToString(); @@ -6858,15 +6851,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0); } - /// - /// This is a depecated function so this just replicates the result of - /// invoking it in SL - /// public void llRemoteLoadScript(string target, string name, int running, int start_param) { m_host.AddScriptLPS(1); - // Report an error as it does in SL - ShoutError("Deprecated. Please use llRemoteLoadScriptPin instead."); + Deprecated("llRemoteLoadScript", "Use llRemoteLoadScriptPin instead"); ScriptSleep(3000); } @@ -6884,7 +6872,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(target, out destId)) { - llSay(0, "Could not parse key " + target); + Error("llRemoteLoadScriptPin", "Can't parse key '" + target + "'"); return; } @@ -6900,7 +6888,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // make sure the object is a script if (item == null || item.Type != 10) { - llSay(0, "Could not find script " + name); + Error("llRemoteLoadScriptPin", "Can't find script '" + name + "'"); return; } @@ -7948,9 +7936,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } catch (InvalidCastException e) { - ShoutError(string.Format( - "{0} error running rule #{1}: arg #{2} ", - originFunc, rulesParsed, idx - idxStart) + e.Message); + Error(originFunc, string.Format("Error running rule #{0}: arg #{1} - ", rulesParsed, idx - idxStart) + e.Message); } finally { @@ -7983,9 +7969,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api string encodedData = Convert.ToBase64String(encData_byte); return encodedData; } - catch (Exception e) + catch { - throw new Exception("Error in base64Encode" + e.Message); + Error("llBase64ToString", "Error encoding string"); + return String.Empty; } } @@ -7996,16 +7983,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { return Util.Base64ToString(str); } - catch (Exception e) + catch { - throw new Exception("Error in base64Decode" + e.Message); + Error("llBase64ToString", "Error decoding string"); + return String.Empty; } } public LSL_String llXorBase64Strings(string str1, string str2) { m_host.AddScriptLPS(1); - Deprecated("llXorBase64Strings"); + Deprecated("llXorBase64Strings", "Use llXorBase64 instead"); ScriptSleep(300); return String.Empty; } @@ -8013,7 +8001,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llRemoteDataSetRegion() { m_host.AddScriptLPS(1); - Deprecated("llRemoteDataSetRegion"); + Deprecated("llRemoteDataSetRegion", "Use llOpenRemoteDataChannel instead"); } public LSL_Float llLog10(double val) @@ -9728,7 +9716,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (item == null) { - llSay(0, "No item name '" + item + "'"); + Error("llGetInventoryCreator", "Can't find item '" + item + "'"); return String.Empty; } @@ -10047,7 +10035,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api presence = World.GetScenePresence(agentID); } } - else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AGENT must be a key"); + else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_AGENT must be a key"); ++i; } break; @@ -10078,7 +10066,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api url = (LSL_String)commandList.Data[i + 1]; update = true; } - else ShoutError("The argument of PARCEL_MEDIA_COMMAND_URL must be a string."); + else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_URL must be a string"); ++i; } break; @@ -10091,7 +10079,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api texture = (LSL_String)commandList.Data[i + 1]; update = true; } - else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TEXTURE must be a string or key."); + else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_TEXTURE must be a string or a key"); ++i; } break; @@ -10103,7 +10091,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { time = (float)(LSL_Float)commandList.Data[i + 1]; } - else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TIME must be a float."); + else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_TIME must be a float"); ++i; } break; @@ -10117,7 +10105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api update = true; } - else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AUTO_ALIGN must be an integer."); + else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_AUTO_ALIGN must be an integer"); ++i; } break; @@ -10130,7 +10118,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api mediaType = (LSL_String)commandList.Data[i + 1]; update = true; } - else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TYPE must be a string."); + else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_TYPE must be a string"); ++i; } break; @@ -10143,7 +10131,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api description = (LSL_String)commandList.Data[i + 1]; update = true; } - else ShoutError("The argument of PARCEL_MEDIA_COMMAND_DESC must be a string."); + else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_DESC must be a string"); ++i; } break; @@ -10159,15 +10147,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api height = (LSL_Integer)commandList.Data[i + 2]; update = true; } - else ShoutError("The second argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer."); + else Error("llParcelMediaCommandList", "The second argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer"); } - else ShoutError("The first argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer."); + else Error("llParcelMediaCommandList", "The first argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer"); i += 2; } break; default: - NotImplemented("llParcelMediaCommandList parameter not supported yet: " + Enum.Parse(typeof(ParcelMediaCommandEnum), commandList.Data[i].ToString()).ToString()); + NotImplemented("llParcelMediaCommandList", "Parameter not supported yet: " + Enum.Parse(typeof(ParcelMediaCommandEnum), commandList.Data[i].ToString()).ToString()); break; }//end switch }//end for @@ -10275,7 +10263,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; default: ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; - NotImplemented("llParcelMediaQuery parameter do not supported yet: " + Enum.Parse(mediaCommandEnum.GetType() , aList.Data[i].ToString()).ToString()); + NotImplemented("llParcelMediaQuery", "Parameter not supported yet: " + Enum.Parse(mediaCommandEnum.GetType() , aList.Data[i].ToString()).ToString()); break; } @@ -10312,7 +10300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (quick_pay_buttons.Data.Length < 4) { - LSLError("List must have at least 4 elements"); + Error("llSetPayPrice", "List must have at least 4 elements"); return; } m_host.ParentGroup.RootPart.PayPrice[0]=price; @@ -10333,7 +10321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) { - ShoutError("No permissions to track the camera"); + Error("llGetCameraPos", "No permissions to track the camera"); return Vector3.Zero; } @@ -10356,7 +10344,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) { - ShoutError("No permissions to track the camera"); + Error("llGetCameraRot", "No permissions to track the camera"); return Quaternion.Identity; } @@ -10369,24 +10357,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return Quaternion.Identity; } - /// - /// The SL implementation does nothing, it is deprecated - /// This duplicates SL - /// public void llSetPrimURL(string url) { m_host.AddScriptLPS(1); + Deprecated("llSetPrimURL", "Use llSetPrimMediaParams instead"); ScriptSleep(2000); } - /// - /// The SL implementation shouts an error, it is deprecated - /// This duplicates SL - /// public void llRefreshPrimURL() { m_host.AddScriptLPS(1); - ShoutError("llRefreshPrimURL - not yet supported"); + Deprecated("llRefreshPrimURL"); ScriptSleep(20000); } @@ -10696,7 +10677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!ok || flag < 0 || flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE) { - throw new ScriptException("Parameter " + i.ToString() + " is an invalid flag"); + Error("llHTTPRequest", "Parameter " + i.ToString() + " is an invalid flag"); } param.Add(parameters.Data[i].ToString()); //Add parameter flag @@ -10720,12 +10701,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { //There must be at least one name/value pair for custom header if (count == 1) - throw new ScriptException("Missing name/value for custom header at parameter " + i.ToString()); + Error("llHTTPRequest", "Missing name/value for custom header at parameter " + i.ToString()); break; } if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase)) - throw new ScriptException("Name is invalid as a custom header at parameter " + i.ToString()); + Error("llHTTPRequest", "Name is invalid as a custom header at parameter " + i.ToString()); param.Add(parameters.Data[i].ToString()); param.Add(parameters.Data[i+1].ToString()); @@ -11242,25 +11223,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return item.ItemID; } - internal void ShoutError(string msg) + /// + /// Reports the script error in the viewer's Script Warning/Error dialog and shouts it on the debug channel. + /// + /// The name of the command that generated the error. + /// The error message to report to the user. + internal void Error(string command, string message) { - llShout(ScriptBaseClass.DEBUG_CHANNEL, msg); + string text = command + ": " + message; + if (text.Length > 1023) + { + text = text.Substring(0, 1023); + } + + World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, ScriptBaseClass.DEBUG_CHANNEL, + m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false); + + IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); + if (wComm != null) + { + wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, text); + } } - internal void NotImplemented(string command) + /// + /// Reports that the command is not implemented as a script error. + /// + /// The name of the command that is not implemented. + /// Additional information to report to the user. (Optional) + internal void NotImplemented(string command, string message = "") { if (throwErrorOnNotImplemented) - throw new NotImplementedException("Command not implemented: " + command); + { + if (message != "") + { + message = " - " + message; + } + + throw new NotImplementedException("Command not implemented: " + command + message); + } + else + { + string text = "Command not implemented"; + if (message != "") + { + text = text + " - " + message; + } + + Error(command, text); + } } - internal void Deprecated(string command) + /// + /// Reports that the command is deprecated as a script error. + /// + /// The name of the command that is deprecated. + /// Additional information to report to the user. (Optional) + internal void Deprecated(string command, string message = "") { - throw new ScriptException("Command deprecated: " + command); - } + string text = "Command deprecated"; + if (message != "") + { + text = text + " - " + message; + } - internal void LSLError(string msg) - { - throw new ScriptException("LSL Runtime Error: " + msg); + Error(command, text); } public delegate void AssetRequestCallback(UUID assetID, AssetBase asset); @@ -11292,7 +11319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (assetID == UUID.Zero) { // => complain loudly, as specified by the LSL docs - ShoutError("Notecard '" + name + "' could not be found."); + Error("llGetNumberOfNotecardLines", "Can't find notecard '" + name + "'"); return UUID.Zero.ToString(); } @@ -11314,7 +11341,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (a == null || a.Type != 7) { - ShoutError("Notecard '" + name + "' could not be found."); + Error("llGetNumberOfNotecardLines", "Can't find notecard '" + name + "'"); return; } @@ -11345,7 +11372,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (assetID == UUID.Zero) { // => complain loudly, as specified by the LSL docs - ShoutError("Notecard '" + name + "' could not be found."); + Error("llGetNotecardLine", "Can't find notecard '" + name + "'"); return UUID.Zero.ToString(); } @@ -11368,7 +11395,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (a == null || a.Type != 7) { - ShoutError("Notecard '" + name + "' could not be found."); + Error("llGetNotecardLine", "Can't find notecard '" + name + "'"); return; } diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs index beead97e9e..0f8033d614 100644 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs @@ -162,7 +162,7 @@ namespace OpenSim.Services.Connectors finally { if (os != null) - os.Close(); + os.Dispose(); } // Let's wait for the response @@ -202,4 +202,4 @@ namespace OpenSim.Services.Connectors return true; } } -} \ No newline at end of file +} diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 150c2c0dbe..46a5c180e6 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -384,11 +384,30 @@ namespace OpenSim.Services.LLLoginService // GridRegion home = null; GridUserInfo guinfo = m_GridUserService.LoggedIn(account.PrincipalID.ToString()); - if (guinfo != null && (guinfo.HomeRegionID != UUID.Zero) && m_GridService != null) + + // We are only going to complain about no home if the user actually tries to login there, to avoid + // spamming the console. + if (guinfo != null) { - home = m_GridService.GetRegionByUUID(scopeID, guinfo.HomeRegionID); + if (guinfo.HomeRegionID == UUID.Zero && startLocation == "home") + { + m_log.WarnFormat( + "[LLOGIN SERVICE]: User {0} tried to login to a 'home' start location but they have none set", + account.Name); + } + else if (m_GridService != null) + { + home = m_GridService.GetRegionByUUID(scopeID, guinfo.HomeRegionID); + + if (home == null && startLocation == "home") + { + m_log.WarnFormat( + "[LLOGIN SERVICE]: User {0} tried to login to a 'home' start location with ID {1} but this was not found.", + account.Name, guinfo.HomeRegionID); + } + } } - if (guinfo == null) + else { // something went wrong, make something up, so that we don't have to test this anywhere else m_log.DebugFormat("{0} Failed to fetch GridUserInfo. Creating empty GridUserInfo as home", LogHeader); @@ -509,10 +528,6 @@ namespace OpenSim.Services.LLLoginService if (home == null) { - m_log.WarnFormat( - "[LLOGIN SERVICE]: User {0} {1} tried to login to a 'home' start location but they have none set", - account.FirstName, account.LastName); - tryDefaults = true; } else diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs index bef16910b4..bfc27b518c 100644 --- a/OpenSim/Services/UserAccountService/GridUserService.cs +++ b/OpenSim/Services/UserAccountService/GridUserService.cs @@ -48,6 +48,14 @@ namespace OpenSim.Services.UserAccountService { m_log.Debug("[GRID USER SERVICE]: Starting user grid service"); + MainConsole.Instance.Commands.AddCommand( + "Users", false, + "show grid user", + "show grid user ", + "Show grid user entry or entries that match or start with the given ID. This will normally be a UUID.", + "This is for debug purposes to see what data is found for a particular user id.", + HandleShowGridUser); + MainConsole.Instance.Commands.AddCommand( "Users", false, "show grid users online", @@ -58,6 +66,31 @@ namespace OpenSim.Services.UserAccountService HandleShowGridUsersOnline); } + protected void HandleShowGridUser(string module, string[] cmdparams) + { + if (cmdparams.Length != 4) + { + MainConsole.Instance.Output("Usage: show grid user "); + return; + } + + GridUserData[] data = m_Database.GetAll(cmdparams[3]); + + foreach (GridUserData gu in data) + { + ConsoleDisplayList cdl = new ConsoleDisplayList(); + + cdl.AddRow("User ID", gu.UserID); + + foreach (KeyValuePair kvp in gu.Data) + cdl.AddRow(kvp.Key, kvp.Value); + + MainConsole.Instance.Output(cdl.ToString()); + } + + MainConsole.Instance.OutputFormat("Entries: {0}", data.Length); + } + protected void HandleShowGridUsersOnline(string module, string[] cmdparams) { // if (cmdparams.Length != 4) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index df94239801..026f285707 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1001,10 +1001,10 @@ ; Terrain implementation can use either Bullet's heightField or BulletSim can build ; a mesh. 0=heightField, 1=mesh - TerrainImplementation = 1 + TerrainImplementation = 0 ; For mesh terrain, the detail of the created mesh. '1' gives 256x256 (heightfield ; resolution). '2' gives 512x512. Etc. Cannot be larger than '4'. Higher - ; magnification uses lots of memory. + ; magnifications use lots of memory. TerrainMeshMagnification = 2 ; Avatar physics height adjustments.