Преглед на файлове

Merge branch 'master' of [email protected]:/var/git/opensim

Melanie преди 10 години
родител
ревизия
e1d1c27965
променени са 33 файла, в които са добавени 611 реда и са изтрити 355 реда
  1. 5 1
      OpenSim/Data/MSSQL/MSSQLSimulationData.cs
  2. 5 1
      OpenSim/Data/MySQL/MySQLSimulationData.cs
  3. 1 0
      OpenSim/Data/Null/NullSimulationData.cs
  4. 5 1
      OpenSim/Data/PGSQL/PGSQLSimulationData.cs
  5. 5 1
      OpenSim/Data/SQLite/SQLiteSimulationData.cs
  6. 6 1
      OpenSim/Framework/TerrainData.cs
  7. 3 3
      OpenSim/Framework/WebUtil.cs
  8. 10 8
      OpenSim/Region/Application/OpenSim.cs
  9. 35 42
      OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
  10. 3 4
      OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
  11. 31 20
      OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
  12. 36 12
      OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
  13. 1 1
      OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
  14. 4 1
      OpenSim/Region/CoreModules/World/Land/LandObject.cs
  15. 90 91
      OpenSim/Region/CoreModules/World/Sun/SunModule.cs
  16. 4 31
      OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
  17. 17 19
      OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs
  18. 1 1
      OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
  19. 26 0
      OpenSim/Region/Framework/Interfaces/INPCModule.cs
  20. 3 0
      OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
  21. 1 1
      OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
  22. 72 0
      OpenSim/Region/Framework/Scenes/TerrainChannel.cs
  23. 15 2
      OpenSim/Region/Framework/Scenes/UuidGatherer.cs
  24. 1 1
      OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
  25. 14 1
      OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
  26. 24 2
      OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
  27. 1 1
      OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
  28. 8 0
      OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
  29. 125 98
      OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
  30. 2 2
      OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs
  31. 22 7
      OpenSim/Services/LLLoginService/LLLoginService.cs
  32. 33 0
      OpenSim/Services/UserAccountService/GridUserService.cs
  33. 2 2
      bin/OpenSimDefaults.ini

+ 5 - 1
OpenSim/Data/MSSQL/MSSQLSimulationData.cs

@@ -531,10 +531,14 @@ ELSE
         /// <returns></returns>
         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;

+ 5 - 1
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;

+ 1 - 0
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))

+ 5 - 1
OpenSim/Data/PGSQL/PGSQLSimulationData.cs

@@ -524,10 +524,14 @@ namespace OpenSim.Data.PGSQL
         /// <returns></returns>
         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;

+ 5 - 1
OpenSim/Data/SQLite/SQLiteSimulationData.cs

@@ -870,10 +870,14 @@ namespace OpenSim.Data.SQLite
         /// <returns>Heightfield data</returns>
         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;

+ 6 - 1
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)

+ 3 - 3
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;
         }
     }
-}
+}

+ 10 - 8
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 \"<x,y,z>\"]"
+                                             + " [--force-terrain] [--force-parcels]"
+                                             + " [--no-objects]"
+                                             + " [--rotation degrees] [--rotation-center \"<x,y,z>\"]"
                                              + " [--displacement \"<x,y,z>\"]"
                                              + " [<OAR path>]",
                                           "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);

+ 35 - 42
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
-            {
-                mret = (OSDMap)OSDParser.DeserializeJson(rstream);
-            }
-            catch (Exception e)
+            using (webResponse)
+            using (Stream rstream = webResponse.GetResponseStream())
             {
-                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;
+            }
         }
 
         /// <summary>
@@ -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
-            {
-                response = (OSDMap)OSDParser.DeserializeJson(rstream);
-            }
-            catch (Exception e)
+            using (webResponse)
+            using (Stream rstream = webResponse.GetResponseStream())
             {
-                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;
+                data = response;
 
-            return true;
+                return true;
+            }
         }
+
         #endregion Web Util
     }
-}
+}

+ 3 - 4
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();
         }
     }
-}
+}

+ 31 - 20
OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs

@@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
         protected Vector3 m_displacement = Vector3.Zero;
 
         /// <value>
-        /// Rotation to apply to the objects as they are loaded.
+        /// Rotation (in radians) to apply to the objects as they are loaded.
         /// </value>
         protected float m_rotation = 0f;
 
@@ -130,6 +130,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
         /// </value>
         protected Vector3 m_rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f);
 
+        protected bool m_noObjects = false;
+
         /// <summary>
         /// Used to cache lookups for valid uuids.
         /// </summary>
@@ -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)
-                    {
-                        sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation;
-                        Vector3 offset = sceneObject.AbsolutePosition - m_rotationCenter;
-                        offset *= rot;
-                        sceneObject.AbsolutePosition = m_rotationCenter + offset;
-                    }
-                    if (m_displacement != Vector3.Zero)
+                    if (m_displacement != Vector3.Zero || m_rotation != 0f)
                     {
-                        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<ITerrainModule>();
 
             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
             {

+ 36 - 12
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<float>(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<float>(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<string, object> archiveOptions = new Dictionary<string, object>();
             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)
             {

+ 1 - 1
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;

+ 4 - 1
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)

+ 90 - 91
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} [<value>]", 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<string, string> Params = new Dictionary<string, string>();
 
             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;

+ 4 - 31
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);
         }
 
         /// <summary>
@@ -325,7 +324,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
         /// </summary>
         /// <param name="filename">Filename to terrain file. Type is determined by extension.</param>
         /// <param name="stream"></param>
-        public void LoadFromStream(string filename, Vector2 displacement, Stream stream)
+        public void LoadFromStream(string filename, Vector3 displacement,
+                                float radianRotation, Vector2 rotationDisplacement, Stream stream)
         {
             foreach (KeyValuePair<string, ITerrainLoader> 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);

+ 17 - 19
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.");

+ 1 - 1
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;

+ 26 - 0
OpenSim/Region/Framework/Interfaces/INPCModule.cs

@@ -71,6 +71,32 @@ namespace OpenSim.Region.Framework.Interfaces
                 UUID owner, bool senseAsAgent, Scene scene,
                 AvatarAppearance appearance);
 
+        /// <summary>
+        /// Create an NPC with a user-supplied agentID
+        /// </summary>
+        /// <param name="firstname"></param>
+        /// <param name="lastname"></param>
+        /// <param name="position"></param>
+        /// <param name="agentID"></param>
+        /// The desired agent ID
+        /// <param name="owner"></param>
+        /// <param name="senseAsAgent">
+        /// 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.
+        /// </param>
+        /// <param name="scene"></param>
+        /// <param name="appearance">
+        /// The avatar appearance to use for the new NPC.
+        /// </param>
+        /// <returns>
+        /// The UUID of the ScenePresence created. UUID.Zero if there was a
+        /// failure.
+        /// </returns>
+        UUID CreateNPC(string firstname, string lastname,
+                Vector3 position, UUID agentID, UUID owner, bool senseAsAgent, Scene scene,
+                AvatarAppearance appearance);
+
         /// <summary>
         /// Check if the agent is an NPC.
         /// </summary>

+ 3 - 0
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);
     }
 }

+ 1 - 1
OpenSim/Region/Framework/Interfaces/ITerrainModule.cs

@@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Interfaces
         /// </param>
         /// <param name="stream"></param>
         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);
         /// <summary>
         /// Save a terrain to a stream.

+ 72 - 0
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()

+ 15 - 2
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
             }
         }
 
+        /// <summary>
+        /// Gather all the asset uuids found in one face of a Texture Entry.
+        /// </summary>
+        private void GatherTextureEntryAssets(Primitive.TextureEntryFace texture, IDictionary<UUID, sbyte> assetUuids)
+        {
+            assetUuids[texture.TextureID] = (sbyte)AssetType.Texture;
+
+            if (texture.MaterialID != UUID.Zero)
+            {
+                GatherAssetUuids(texture.MaterialID, (sbyte)OpenSimAssetType.Material, assetUuids);
+            }
+        }
+
 //        /// <summary>
 //        /// The callback made when we request the asset for an object from the asset service.
 //        /// </summary>

+ 1 - 1
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();
             }
         }
     }

+ 14 - 1
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;

+ 24 - 2
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);
 

+ 1 - 1
OpenSim/Region/Physics/BulletSPlugin/BSParam.cs

@@ -538,7 +538,7 @@ public static class BSParam
             (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ),
 
 	    new ParameterDefn<float>("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
-            (float)BSTerrainPhys.TerrainImplementation.Mesh ),
+            (float)BSTerrainPhys.TerrainImplementation.Heightmap ),
         new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" ,
             2 ),
         new ParameterDefn<float>("TerrainFriction", "Factor to reduce movement against terrain surface" ,

+ 8 - 0
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);
 

+ 125 - 98
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs

@@ -101,7 +101,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         /// </summary>
         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<IEmailModule>();
             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<IEmailModule>();
             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");
             }
         }
 
-        /// <summary>
-        /// llSoundPreload is deprecated. In SL this appears to do absolutely nothing
-        /// and is documented to have no delay.
-        /// </summary>
         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);
         }
 
-        /// <summary>
-        /// This is a depecated function so this just replicates the result of
-        /// invoking it in SL
-        /// </summary>
         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;
         }
 
-        /// <summary>
-        /// The SL implementation does nothing, it is deprecated
-        /// This duplicates SL
-        /// </summary>
         public void llSetPrimURL(string url)
         {
             m_host.AddScriptLPS(1);
+            Deprecated("llSetPrimURL", "Use llSetPrimMediaParams instead");
             ScriptSleep(2000);
         }
 
-        /// <summary>
-        /// The SL implementation shouts an error, it is deprecated
-        /// This duplicates SL
-        /// </summary>
         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)
+        /// <summary>
+        /// Reports the script error in the viewer's Script Warning/Error dialog and shouts it on the debug channel.
+        /// </summary>
+        /// <param name="command">The name of the command that generated the error.</param>
+        /// <param name="message">The error message to report to the user.</param>
+        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<IWorldComm>();
+            if (wComm != null)
+            {
+                wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, text);
+            }
         }
 
-        internal void NotImplemented(string command)
+        /// <summary>
+        /// Reports that the command is not implemented as a script error.
+        /// </summary>
+        /// <param name="command">The name of the command that is not implemented.</param>
+        /// <param name="message">Additional information to report to the user. (Optional)</param>
+        internal void NotImplemented(string command, string message = "")
         {
             if (throwErrorOnNotImplemented)
-                throw new NotImplementedException("Command not implemented: " + command);
-        }
+            {
+                if (message != "")
+                {
+                    message = " - " + message;
+                }
 
-        internal void Deprecated(string command)
-        {
-            throw new ScriptException("Command deprecated: " + command);
+                throw new NotImplementedException("Command not implemented: " + command + message);
+            }
+            else
+            {
+                string text = "Command not implemented";
+                if (message != "")
+                {
+                    text = text + " - " + message;
+                }
+
+                Error(command, text);
+            }
         }
 
-        internal void LSLError(string msg)
+        /// <summary>
+        /// Reports that the command is deprecated as a script error.
+        /// </summary>
+        /// <param name="command">The name of the command that is deprecated.</param>
+        /// <param name="message">Additional information to report to the user. (Optional)</param>
+        internal void Deprecated(string command, string message = "")
         {
-            throw new ScriptException("LSL Runtime Error: " + msg);
+            string text = "Command deprecated";
+            if (message != "")
+            {
+                text = text + " - " + message;
+            }
+
+            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;
                              }
 

+ 2 - 2
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;
         }
     }
-}
+}

+ 22 - 7
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

+ 33 - 0
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 <ID>",
+                "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 <UUID>");
+                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<string,string> 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)

+ 2 - 2
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.