From 5b19d5a7b763a5ff5a7380f00c08fc30f4707588 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 4 Oct 2009 14:05:58 -0700 Subject: Reduced locking. --- OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index facfb9d..2120d33 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs @@ -167,8 +167,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP J2KImage imagereq; int numCollected = 0; - lock (m_syncRoot) - { + //lock (m_syncRoot) + //{ m_lastloopprocessed = DateTime.Now.Ticks; // This can happen during Close() @@ -191,7 +191,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (numCollected == count) break; } - } + //} return m_priorityQueue.Count > 0; } @@ -211,16 +211,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP { J2KImage image = null; - if (m_priorityQueue.Count > 0) + lock (m_priorityQueue) { - try + + if (m_priorityQueue.Count > 0) { - lock (m_priorityQueue) + try + { image = m_priorityQueue.FindMax(); + } + catch (Exception) { } } - catch (Exception) { } } - return image; } -- cgit v1.1 From 362e94a0229d0b450001b8b089a472b550b530f3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 4 Oct 2009 16:30:12 -0700 Subject: * KeepAlive set to false in expect_user and log_off. * Check for null SP in PermissionsModule. --- OpenSim/Client/Linden/LLProxyLoginModule.cs | 4 ++-- .../CoreModules/World/Permissions/PermissionsModule.cs | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/Linden/LLProxyLoginModule.cs b/OpenSim/Client/Linden/LLProxyLoginModule.cs index 195feaf..f9cb3a9 100644 --- a/OpenSim/Client/Linden/LLProxyLoginModule.cs +++ b/OpenSim/Client/Linden/LLProxyLoginModule.cs @@ -148,8 +148,8 @@ namespace OpenSim.Client.Linden protected void AddHttpHandlers() { //we will add our handlers to the first scene we received, as all scenes share a http server. But will this ever change? - MainServer.Instance.AddXmlRPCHandler("expect_user", ExpectUser); - MainServer.Instance.AddXmlRPCHandler("logoff_user", LogOffUser); + MainServer.Instance.AddXmlRPCHandler("expect_user", ExpectUser, false); + MainServer.Instance.AddXmlRPCHandler("logoff_user", LogOffUser, false); } protected void AddScene(Scene scene) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 9622555..901144a 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -397,10 +397,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions // with the powers requested (powers = 0 for no powers check) protected bool IsGroupMember(UUID groupID, UUID userID, ulong powers) { - IClientAPI client = m_scene.GetScenePresence(userID).ControllingClient; - - return ((groupID == client.ActiveGroupId) && (client.ActiveGroupPowers != 0) && - ((powers == 0) || ((client.ActiveGroupPowers & powers) == powers))); + ScenePresence sp = m_scene.GetScenePresence(userID); + if (sp != null) + { + IClientAPI client = sp.ControllingClient; + + return ((groupID == client.ActiveGroupId) && (client.ActiveGroupPowers != 0) && + ((powers == 0) || ((client.ActiveGroupPowers & powers) == powers))); + } + return false; } /// -- cgit v1.1 From a208f33c5dc4784f97dc3cd46cb56e79cc457f82 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 5 Oct 2009 00:23:47 +0100 Subject: Make the asset connector async Get overload return false if the asset retrieval was not synchronous. --- OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index b1d41da..6f7c90f 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -171,6 +171,8 @@ namespace OpenSim.Services.Connectors if (asset == null) { + bool result = false; + AsynchronousRestObjectRequester. MakeRequest("GET", uri, 0, delegate(AssetBase a) @@ -178,8 +180,10 @@ namespace OpenSim.Services.Connectors if (m_Cache != null) m_Cache.Cache(a); handler(id, sender, a); + result = true; }); + return result; } else { -- cgit v1.1 From 5c593f3892d3de0bc3dab25c9298a3f31d3d86c1 Mon Sep 17 00:00:00 2001 From: dahlia Date: Sun, 4 Oct 2009 20:01:44 -0700 Subject: only cache mesh if meshing was successful re-enable sculpt mesh caching --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 0e29ccc..1ea08e2 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -498,12 +498,9 @@ namespace OpenSim.Region.Physics.Meshing // If this mesh has been created already, return it instead of creating another copy // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory - if (! primShape.SculptEntry) - { - key = GetMeshKey(primShape, size, lod); - if (m_uniqueMeshes.TryGetValue(key, out mesh)) - return mesh; - } + key = GetMeshKey(primShape, size, lod); + if (m_uniqueMeshes.TryGetValue(key, out mesh)) + return mesh; if (size.X < 0.01f) size.X = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f; @@ -525,10 +522,9 @@ namespace OpenSim.Region.Physics.Meshing // trim the vertex and triangle lists to free up memory mesh.TrimExcess(); - } - if (!primShape.SculptEntry) m_uniqueMeshes.Add(key, mesh); + } return mesh; } -- cgit v1.1 From 6d52974c5f8184c03e3366fdcce03e4ec15c85f6 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Mon, 5 Oct 2009 05:35:56 -0700 Subject: Eliminate pinned Mesh data on managed heap by using IntPtrs to memory allocated on the unmanaged heap. This prevents fragmentation of the managed heap and the resulting stress on GC. A region with ~150,000 prims using ODE and Meshmerizer saw memory remain flat around 1.2GB as opposed to 1.5GB and continually growing due to pinned memory. This patch complements the unique mesh dictionary patch applied to Meshmerizer but is independent. The net effect is a 60-75% reduction in memory for our largest regions. --- OpenSim/Region/Physics/Manager/IMesher.cs | 2 + OpenSim/Region/Physics/Meshing/Mesh.cs | 166 +++++++++++++++++++--------- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 13 +-- 3 files changed, 120 insertions(+), 61 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index e26c623..ac14292 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs @@ -47,6 +47,8 @@ namespace OpenSim.Region.Physics.Manager int[] getIndexListAsInt(); int[] getIndexListAsIntLocked(); float[] getVertexListAsFloatLocked(); + void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount); + void getVertexListAsPtrToFloatArray( out IntPtr vertexList, out int vertexStride, out int vertexCount ); void releaseSourceMeshData(); void releasePinned(); void Append(IMesh newMesh); diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs index aae8871..ff1f816 100644 --- a/OpenSim/Region/Physics/Meshing/Mesh.cs +++ b/OpenSim/Region/Physics/Meshing/Mesh.cs @@ -36,23 +36,27 @@ namespace OpenSim.Region.Physics.Meshing { public class Mesh : IMesh { - private Dictionary vertices; - private List triangles; - GCHandle pinnedVirtexes; - GCHandle pinnedIndex; - public float[] normals; + private Dictionary m_vertices; + private List m_triangles; + GCHandle m_pinnedVertexes; + GCHandle m_pinnedIndex; + IntPtr m_verticesPtr = IntPtr.Zero; + int m_vertexCount = 0; + IntPtr m_indicesPtr = IntPtr.Zero; + int m_indexCount = 0; + public float[] m_normals; public Mesh() { - vertices = new Dictionary(); - triangles = new List(); + m_vertices = new Dictionary(); + m_triangles = new List(); } public Mesh Clone() { Mesh result = new Mesh(); - foreach (Triangle t in triangles) + foreach (Triangle t in m_triangles) { result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); } @@ -62,27 +66,27 @@ namespace OpenSim.Region.Physics.Meshing public void Add(Triangle triangle) { - if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated) + if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) throw new NotSupportedException("Attempt to Add to a pinned Mesh"); // If a vertex of the triangle is not yet in the vertices list, // add it and set its index to the current index count - if (!vertices.ContainsKey(triangle.v1)) - vertices[triangle.v1] = vertices.Count; - if (!vertices.ContainsKey(triangle.v2)) - vertices[triangle.v2] = vertices.Count; - if (!vertices.ContainsKey(triangle.v3)) - vertices[triangle.v3] = vertices.Count; - triangles.Add(triangle); + if( !m_vertices.ContainsKey(triangle.v1) ) + m_vertices[triangle.v1] = m_vertices.Count; + if (!m_vertices.ContainsKey(triangle.v2)) + m_vertices[triangle.v2] = m_vertices.Count; + if (!m_vertices.ContainsKey(triangle.v3)) + m_vertices[triangle.v3] = m_vertices.Count; + m_triangles.Add(triangle); } public void CalcNormals() { - int iTriangles = triangles.Count; + int iTriangles = m_triangles.Count; - this.normals = new float[iTriangles * 3]; + this.m_normals = new float[iTriangles * 3]; int i = 0; - foreach (Triangle t in triangles) + foreach (Triangle t in m_triangles) { float ux, uy, uz; float vx, vy, vz; @@ -129,9 +133,9 @@ namespace OpenSim.Region.Physics.Meshing //ny /= l; //nz /= l; - normals[i] = nx * lReciprocal; - normals[i + 1] = ny * lReciprocal; - normals[i + 2] = nz * lReciprocal; + m_normals[i] = nx * lReciprocal; + m_normals[i + 1] = ny * lReciprocal; + m_normals[i + 2] = nz * lReciprocal; i += 3; } @@ -140,45 +144,70 @@ namespace OpenSim.Region.Physics.Meshing public List getVertexList() { List result = new List(); - foreach (Vertex v in vertices.Keys) + foreach (Vertex v in m_vertices.Keys) { result.Add(v); } return result; } - public float[] getVertexListAsFloatLocked() + private float[] getVertexListAsFloat() { - if (pinnedVirtexes.IsAllocated) - return (float[])(pinnedVirtexes.Target); - float[] result; - - //m_log.WarnFormat("vertices.Count = {0}", vertices.Count); - result = new float[vertices.Count * 3]; - foreach (KeyValuePair kvp in vertices) + if(m_vertices == null) + throw new NotSupportedException(); + float[] result = new float[m_vertices.Count * 3]; + foreach (KeyValuePair kvp in m_vertices) { Vertex v = kvp.Key; int i = kvp.Value; - //m_log.WarnFormat("kvp.Value = {0}", i); result[3 * i + 0] = v.X; result[3 * i + 1] = v.Y; result[3 * i + 2] = v.Z; } - pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned); return result; } - public int[] getIndexListAsInt() + public float[] getVertexListAsFloatLocked() { - int[] result; + if( m_pinnedVertexes.IsAllocated ) + return (float[])(m_pinnedVertexes.Target); - result = new int[triangles.Count * 3]; - for (int i = 0; i < triangles.Count; i++) + float[] result = getVertexListAsFloat(); + m_pinnedVertexes = GCHandle.Alloc(result, GCHandleType.Pinned); + + return result; + } + + public void getVertexListAsPtrToFloatArray(out IntPtr vertices, out int vertexStride, out int vertexCount) + { + // A vertex is 3 floats + vertexStride = 3 * sizeof(float); + + // If there isn't an unmanaged array allocated yet, do it now + if (m_verticesPtr == IntPtr.Zero) { - Triangle t = triangles[i]; - result[3 * i + 0] = vertices[t.v1]; - result[3 * i + 1] = vertices[t.v2]; - result[3 * i + 2] = vertices[t.v3]; + float[] vertexList = getVertexListAsFloat(); + // Each vertex is 3 elements (floats) + m_vertexCount = vertexList.Length / 3; + int byteCount = m_vertexCount * vertexStride; + m_verticesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount); + System.Runtime.InteropServices.Marshal.Copy(vertexList, 0, m_verticesPtr, m_vertexCount * 3); + } + vertices = m_verticesPtr; + vertexCount = m_vertexCount; + } + + public int[] getIndexListAsInt() + { + if (m_triangles == null) + throw new NotSupportedException(); + int[] result = new int[m_triangles.Count * 3]; + for (int i = 0; i < m_triangles.Count; i++) + { + Triangle t = m_triangles[i]; + result[3 * i + 0] = m_vertices[t.v1]; + result[3 * i + 1] = m_vertices[t.v2]; + result[3 * i + 2] = m_vertices[t.v3]; } return result; } @@ -189,19 +218,48 @@ namespace OpenSim.Region.Physics.Meshing /// public int[] getIndexListAsIntLocked() { - if (pinnedIndex.IsAllocated) - return (int[])(pinnedIndex.Target); + if (m_pinnedIndex.IsAllocated) + return (int[])(m_pinnedIndex.Target); int[] result = getIndexListAsInt(); - pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned); + m_pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned); return result; } + public void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount) + { + // If there isn't an unmanaged array allocated yet, do it now + if (m_indicesPtr == IntPtr.Zero) + { + int[] indexList = getIndexListAsInt(); + m_indexCount = indexList.Length; + int byteCount = m_indexCount * sizeof(int); + m_indicesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount); + System.Runtime.InteropServices.Marshal.Copy(indexList, 0, m_indicesPtr, m_indexCount); + } + // A triangle is 3 ints (indices) + triStride = 3 * sizeof(int); + indices = m_indicesPtr; + indexCount = m_indexCount; + } + public void releasePinned() { - pinnedVirtexes.Free(); - pinnedIndex.Free(); + if (m_pinnedVertexes.IsAllocated) + m_pinnedVertexes.Free(); + if (m_pinnedIndex.IsAllocated) + m_pinnedIndex.Free(); + if (m_verticesPtr != IntPtr.Zero) + { + System.Runtime.InteropServices.Marshal.FreeHGlobal(m_verticesPtr); + m_verticesPtr = IntPtr.Zero; + } + if (m_indicesPtr != IntPtr.Zero) + { + System.Runtime.InteropServices.Marshal.FreeHGlobal(m_indicesPtr); + m_indicesPtr = IntPtr.Zero; + } } /// @@ -209,29 +267,29 @@ namespace OpenSim.Region.Physics.Meshing /// public void releaseSourceMeshData() { - triangles = null; - vertices = null; + m_triangles = null; + m_vertices = null; } public void Append(IMesh newMesh) { - if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated) + if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) throw new NotSupportedException("Attempt to Append to a pinned Mesh"); if (!(newMesh is Mesh)) return; - foreach (Triangle t in ((Mesh)newMesh).triangles) + foreach (Triangle t in ((Mesh)newMesh).m_triangles) Add(t); } // Do a linear transformation of mesh. public void TransformLinear(float[,] matrix, float[] offset) { - if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated) + if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh"); - foreach (Vertex v in vertices.Keys) + foreach (Vertex v in m_vertices.Keys) { if (v == null) continue; @@ -252,7 +310,7 @@ namespace OpenSim.Region.Physics.Meshing String fileName = name + "_" + title + ".raw"; String completePath = Path.Combine(path, fileName); StreamWriter sw = new StreamWriter(completePath); - foreach (Triangle t in triangles) + foreach (Triangle t in m_triangles) { String s = t.ToStringRaw(); sw.WriteLine(s); @@ -262,7 +320,7 @@ namespace OpenSim.Region.Physics.Meshing public void TrimExcess() { - triangles.TrimExcess(); + m_triangles.TrimExcess(); } } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 032b5df..c041243 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -813,18 +813,17 @@ namespace OpenSim.Region.Physics.OdePlugin } } - float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory - int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage + IntPtr vertices, indices; + int vertexCount, indexCount; + int vertexStride, triStride; + mesh.getVertexListAsPtrToFloatArray( out vertices, out vertexStride, out vertexCount ); // Note, that vertices are fixed in unmanaged heap + mesh.getIndexListAsPtrToIntArray( out indices, out triStride, out indexCount ); // Also fixed, needs release after usage mesh.releaseSourceMeshData(); // free up the original mesh data to save memory - int VertexCount = vertexList.GetLength(0)/3; - int IndexCount = indexList.GetLength(0); - _triMeshData = d.GeomTriMeshDataCreate(); - d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3*sizeof (float), VertexCount, indexList, IndexCount, - 3*sizeof (int)); + d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); d.GeomTriMeshDataPreprocess(_triMeshData); _parent_scene.waitForSpaceUnlock(m_targetSpace); -- cgit v1.1 From 7c3e5afc0c983e490401253e16c49ff401e61b65 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 5 Oct 2009 17:04:36 +0100 Subject: MSSQL changes for Grid server in ROBUST plus some code tweaks 'n tidy up --- OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs | 39 +- OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 1531 ++++++++++++++++++++++ OpenSim/Data/MSSQL/MSSQLRegionData.cs | 1616 +++--------------------- OpenSim/Data/MSSQL/MSSQLUserAccountData.cs | 38 +- OpenSim/Data/MSSQL/Resources/006_GridStore.sql | 8 + 5 files changed, 1776 insertions(+), 1456 deletions(-) create mode 100644 OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs create mode 100644 OpenSim/Data/MSSQL/Resources/006_GridStore.sql (limited to 'OpenSim') diff --git a/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs b/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs index 099faea..9a17e47 100644 --- a/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs +++ b/OpenSim/Data/MSSQL/MSSQLAuthenticationData.cs @@ -43,6 +43,7 @@ namespace OpenSim.Data.MSSQL private List m_ColumnNames = null; private int m_LastExpire = 0; private string m_ConnectionString; + private MSSQLManager m_database; public MSSQLAuthenticationData(string connectionString, string realm) { @@ -61,12 +62,12 @@ namespace OpenSim.Data.MSSQL AuthenticationData ret = new AuthenticationData(); ret.Data = new Dictionary(); - string sql = string.Format("select * from '{0}' where UUID = @principalID", m_Realm); + string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm); using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@principalID", principalID.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); conn.Open(); using (SqlDataReader result = cmd.ExecuteReader()) { @@ -108,34 +109,33 @@ namespace OpenSim.Data.MSSQL using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand()) { - updateBuilder.AppendFormat("update '{0}' set ", m_Realm); + updateBuilder.AppendFormat("update {0} set ", m_Realm); bool first = true; foreach (string field in fields) { if (!first) updateBuilder.Append(", "); - updateBuilder.AppendFormat("'{0}' = @{0}",field); + updateBuilder.AppendFormat("{0} = @{0}",field); first = false; - - cmd.Parameters.AddWithValue("@" + field, data.Data[field]); + cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field])); } updateBuilder.Append(" where UUID = @principalID"); cmd.CommandText = updateBuilder.ToString(); cmd.Connection = conn; - - cmd.Parameters.AddWithValue("@principalID", data.PrincipalID.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID)); + conn.Open(); if (cmd.ExecuteNonQuery() < 1) { StringBuilder insertBuilder = new StringBuilder(); - insertBuilder.AppendFormat("insert into '{0}' ('UUID', '", m_Realm); - insertBuilder.Append(String.Join("', '", fields)); - insertBuilder.Append("') values (@principalID, @"); + insertBuilder.AppendFormat("insert into {0} (UUID, ", m_Realm); + insertBuilder.Append(String.Join(", ", fields)); + insertBuilder.Append(") values ( @principalID, @"); insertBuilder.Append(String.Join(", @", fields)); insertBuilder.Append(")"); @@ -152,12 +152,11 @@ namespace OpenSim.Data.MSSQL public bool SetDataItem(UUID principalID, string item, string value) { - string sql = string.Format("update '{0}' set '{1}' = @{1} where UUID = @UUID", m_Realm, item); + string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item); using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@" + item, value); - cmd.Parameters.AddWithValue("@UUID", principalID.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@" + item, value)); conn.Open(); if (cmd.ExecuteNonQuery() > 0) return true; @@ -173,9 +172,9 @@ namespace OpenSim.Data.MSSQL using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@principalID", principalID.ToString()); - cmd.Parameters.AddWithValue("@token", token); - cmd.Parameters.AddWithValue("@lifetime", lifetime.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); + cmd.Parameters.Add(m_database.CreateParameter("@token", token)); + cmd.Parameters.Add(m_database.CreateParameter("@lifetime", lifetime)); conn.Open(); if (cmd.ExecuteNonQuery() > 0) @@ -194,9 +193,9 @@ namespace OpenSim.Data.MSSQL using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@principalID", principalID.ToString()); - cmd.Parameters.AddWithValue("@token", token); - cmd.Parameters.AddWithValue("@lifetime", lifetime.ToString()); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); + cmd.Parameters.Add(m_database.CreateParameter("@token", token)); + cmd.Parameters.Add(m_database.CreateParameter("@lifetime", lifetime)); conn.Open(); if (cmd.ExecuteNonQuery() > 0) diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs new file mode 100644 index 0000000..adedcce --- /dev/null +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -0,0 +1,1531 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Drawing; +using System.IO; +using System.Reflection; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Data.MSSQL +{ + /// + /// A MSSQL Interface for the Region Server. + /// + public class MSSQLRegionDataStore : IRegionDataStore + { + private const string _migrationStore = "RegionStore"; + + // private static FileSystemDataStore Instance = new FileSystemDataStore(); + private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The database manager + /// + private MSSQLManager _Database; + + /// + /// Initialises the region datastore + /// + /// The connection string. + public void Initialise(string connectionString) + { + if (!string.IsNullOrEmpty(connectionString)) + { + _Database = new MSSQLManager(connectionString); + } + else + { + IniFile iniFile = new IniFile("mssql_connection.ini"); + string settingDataSource = iniFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); + string settingUserId = iniFile.ParseFileReadValue("user_id"); + string settingPassword = iniFile.ParseFileReadValue("password"); + + _Database = new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, settingPassword); + } + + //Migration settings + _Database.CheckMigration(_migrationStore); + } + + /// + /// Dispose the database + /// + public void Dispose() { } + + #region SceneObjectGroup region for loading and Store of the scene. + + /// + /// Loads the objects present in the region. + /// + /// The region UUID. + /// + public List LoadObjects(UUID regionUUID) + { + UUID lastGroupID = UUID.Zero; + + Dictionary prims = new Dictionary(); + Dictionary objects = new Dictionary(); + SceneObjectGroup grp = null; + + + string query = "SELECT *, " + + "sort = CASE WHEN prims.UUID = prims.SceneGroupID THEN 0 ELSE 1 END " + + "FROM prims " + + "LEFT JOIN primshapes ON prims.UUID = primshapes.UUID " + + "WHERE RegionUUID = @RegionUUID " + + "ORDER BY SceneGroupID asc, sort asc, LinkNumber asc"; + + using (AutoClosingSqlCommand command = _Database.Query(query)) + { + command.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + SceneObjectPart sceneObjectPart = BuildPrim(reader); + if (reader["Shape"] is DBNull) + sceneObjectPart.Shape = PrimitiveBaseShape.Default; + else + sceneObjectPart.Shape = BuildShape(reader); + + prims[sceneObjectPart.UUID] = sceneObjectPart; + + UUID groupID = new UUID((Guid)reader["SceneGroupID"]); + + if (groupID != lastGroupID) // New SOG + { + if (grp != null) + objects[grp.UUID] = grp; + + lastGroupID = groupID; + + // There sometimes exist OpenSim bugs that 'orphan groups' so that none of the prims are + // recorded as the root prim (for which the UUID must equal the persisted group UUID). In + // this case, force the UUID to be the same as the group UUID so that at least these can be + // deleted (we need to change the UUID so that any other prims in the linkset can also be + // deleted). + if (sceneObjectPart.UUID != groupID && groupID != UUID.Zero) + { + _Log.WarnFormat( + "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID", + sceneObjectPart.Name, sceneObjectPart.UUID, sceneObjectPart.GroupPosition, groupID); + + sceneObjectPart.UUID = groupID; + } + + grp = new SceneObjectGroup(sceneObjectPart); + } + else + { + // Black magic to preserve link numbers + // Why is this needed, fix this in AddPart method. + int link = sceneObjectPart.LinkNum; + + grp.AddPart(sceneObjectPart); + + if (link != 0) + sceneObjectPart.LinkNum = link; + } + } + } + } + + if (grp != null) + objects[grp.UUID] = grp; + + // Instead of attempting to LoadItems on every prim, + // most of which probably have no items... get a + // list from DB of all prims which have items and + // LoadItems only on those + List primsWithInventory = new List(); + string qry = "select distinct primID from primitems"; + using (AutoClosingSqlCommand command = _Database.Query(qry)) + { + using (SqlDataReader itemReader = command.ExecuteReader()) + { + while (itemReader.Read()) + { + if (!(itemReader["primID"] is DBNull)) + { + UUID primID = new UUID(itemReader["primID"].ToString()); + if (prims.ContainsKey(primID)) + { + primsWithInventory.Add(prims[primID]); + } + } + } + } + } + + LoadItems(primsWithInventory); + + _Log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); + + return new List(objects.Values); + } + + /// + /// Load in the prim's persisted inventory. + /// + /// all prims with inventory on a region + private void LoadItems(List allPrimsWithInventory) + { + + using (AutoClosingSqlCommand command = _Database.Query("SELECT * FROM primitems WHERE PrimID = @PrimID")) + { + foreach (SceneObjectPart objectPart in allPrimsWithInventory) + { + command.Parameters.Clear(); + command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID)); + + List inventory = new List(); + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + TaskInventoryItem item = BuildItem(reader); + + item.ParentID = objectPart.UUID; // Values in database are + // often wrong + inventory.Add(item); + } + } + + objectPart.Inventory.RestoreInventoryItems(inventory); + } + } + } + + /// + /// Stores all object's details apart from inventory + /// + /// + /// + public void StoreObject(SceneObjectGroup obj, UUID regionUUID) + { + _Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); + + using (SqlConnection conn = _Database.DatabaseConnection()) + { + SqlTransaction transaction = conn.BeginTransaction(); + + try + { + foreach (SceneObjectPart sceneObjectPart in obj.Children.Values) + { + //Update prim + using (SqlCommand sqlCommand = conn.CreateCommand()) + { + sqlCommand.Transaction = transaction; + try + { + StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); + } + catch (SqlException sqlEx) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); + throw; + } + } + + //Update primshapes + using (SqlCommand sqlCommand = conn.CreateCommand()) + { + sqlCommand.Transaction = transaction; + try + { + StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); + } + catch (SqlException sqlEx) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); + throw; + } + } + } + + transaction.Commit(); + } + catch (Exception ex) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message); + try + { + transaction.Rollback(); + } + catch (Exception ex2) + { + //Show error + _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message); + + } + } + } + + } + + /// + /// Stores the prim of the sceneobjectpart. + /// + /// The sceneobjectpart or prim. + /// The SQL command with the transaction. + /// The scenegroup UUID. + /// The region UUID. + private void StoreSceneObjectPrim(SceneObjectPart sceneObjectPart, SqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) + { + //Big query to update or insert a new prim. + //Note for SQL Server 2008 this could be simplified + string queryPrims = @" +IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID) + BEGIN + UPDATE prims SET + CreationDate = @CreationDate, Name = @Name, Text = @Text, Description = @Description, SitName = @SitName, + TouchName = @TouchName, ObjectFlags = @ObjectFlags, OwnerMask = @OwnerMask, NextOwnerMask = @NextOwnerMask, GroupMask = @GroupMask, + EveryoneMask = @EveryoneMask, BaseMask = @BaseMask, PositionX = @PositionX, PositionY = @PositionY, PositionZ = @PositionZ, + GroupPositionX = @GroupPositionX, GroupPositionY = @GroupPositionY, GroupPositionZ = @GroupPositionZ, VelocityX = @VelocityX, + VelocityY = @VelocityY, VelocityZ = @VelocityZ, AngularVelocityX = @AngularVelocityX, AngularVelocityY = @AngularVelocityY, + AngularVelocityZ = @AngularVelocityZ, AccelerationX = @AccelerationX, AccelerationY = @AccelerationY, + AccelerationZ = @AccelerationZ, RotationX = @RotationX, RotationY = @RotationY, RotationZ = @RotationZ, RotationW = @RotationW, + SitTargetOffsetX = @SitTargetOffsetX, SitTargetOffsetY = @SitTargetOffsetY, SitTargetOffsetZ = @SitTargetOffsetZ, + SitTargetOrientW = @SitTargetOrientW, SitTargetOrientX = @SitTargetOrientX, SitTargetOrientY = @SitTargetOrientY, + SitTargetOrientZ = @SitTargetOrientZ, RegionUUID = @RegionUUID, CreatorID = @CreatorID, OwnerID = @OwnerID, GroupID = @GroupID, + LastOwnerID = @LastOwnerID, SceneGroupID = @SceneGroupID, PayPrice = @PayPrice, PayButton1 = @PayButton1, PayButton2 = @PayButton2, + PayButton3 = @PayButton3, PayButton4 = @PayButton4, LoopedSound = @LoopedSound, LoopedSoundGain = @LoopedSoundGain, + TextureAnimation = @TextureAnimation, OmegaX = @OmegaX, OmegaY = @OmegaY, OmegaZ = @OmegaZ, CameraEyeOffsetX = @CameraEyeOffsetX, + CameraEyeOffsetY = @CameraEyeOffsetY, CameraEyeOffsetZ = @CameraEyeOffsetZ, CameraAtOffsetX = @CameraAtOffsetX, + CameraAtOffsetY = @CameraAtOffsetY, CameraAtOffsetZ = @CameraAtOffsetZ, ForceMouselook = @ForceMouselook, + ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, + SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, + ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, + LinkNumber = @LinkNumber + WHERE UUID = @UUID + END +ELSE + BEGIN + INSERT INTO + prims ( + UUID, CreationDate, Name, Text, Description, SitName, TouchName, ObjectFlags, OwnerMask, NextOwnerMask, GroupMask, + EveryoneMask, BaseMask, PositionX, PositionY, PositionZ, GroupPositionX, GroupPositionY, GroupPositionZ, VelocityX, + VelocityY, VelocityZ, AngularVelocityX, AngularVelocityY, AngularVelocityZ, AccelerationX, AccelerationY, AccelerationZ, + RotationX, RotationY, RotationZ, RotationW, SitTargetOffsetX, SitTargetOffsetY, SitTargetOffsetZ, SitTargetOrientW, + SitTargetOrientX, SitTargetOrientY, SitTargetOrientZ, RegionUUID, CreatorID, OwnerID, GroupID, LastOwnerID, SceneGroupID, + PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, + OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, + ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, + ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber + ) VALUES ( + @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, + @EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX, + @VelocityY, @VelocityZ, @AngularVelocityX, @AngularVelocityY, @AngularVelocityZ, @AccelerationX, @AccelerationY, @AccelerationZ, + @RotationX, @RotationY, @RotationZ, @RotationW, @SitTargetOffsetX, @SitTargetOffsetY, @SitTargetOffsetZ, @SitTargetOrientW, + @SitTargetOrientX, @SitTargetOrientY, @SitTargetOrientZ, @RegionUUID, @CreatorID, @OwnerID, @GroupID, @LastOwnerID, @SceneGroupID, + @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, + @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, + @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, + @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber + ) + END"; + + //Set commandtext. + sqlCommand.CommandText = queryPrims; + //Add parameters + sqlCommand.Parameters.AddRange(CreatePrimParameters(sceneObjectPart, sceneGroupID, regionUUID)); + + //Execute the query. If it fails then error is trapped in calling function + sqlCommand.ExecuteNonQuery(); + } + + /// + /// Stores the scene object prim shapes. + /// + /// The sceneobjectpart containing prim shape. + /// The SQL command with the transaction. + /// The scenegroup UUID. + /// The region UUID. + private void StoreSceneObjectPrimShapes(SceneObjectPart sceneObjectPart, SqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) + { + //Big query to or insert or update primshapes + //Note for SQL Server 2008 this can be simplified + string queryPrimShapes = @" +IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID) + BEGIN + UPDATE primshapes SET + Shape = @Shape, ScaleX = @ScaleX, ScaleY = @ScaleY, ScaleZ = @ScaleZ, PCode = @PCode, PathBegin = @PathBegin, + PathEnd = @PathEnd, PathScaleX = @PathScaleX, PathScaleY = @PathScaleY, PathShearX = @PathShearX, PathShearY = @PathShearY, + PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions, + PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin, + ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow, + Texture = @Texture, ExtraParams = @ExtraParams, State = @State + WHERE UUID = @UUID + END +ELSE + BEGIN + INSERT INTO + primshapes ( + UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, + PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, + ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State + ) VALUES ( + @UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY, + @PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin, + @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State + ) + END"; + + //Set commandtext. + sqlCommand.CommandText = queryPrimShapes; + + //Add parameters + sqlCommand.Parameters.AddRange(CreatePrimShapeParameters(sceneObjectPart, sceneGroupID, regionUUID)); + + //Execute the query. If it fails then error is trapped in calling function + sqlCommand.ExecuteNonQuery(); + + } + + /// + /// Removes a object from the database. + /// Meaning removing it from tables Prims, PrimShapes and PrimItems + /// + /// id of scenegroup + /// regionUUID (is this used anyway + public void RemoveObject(UUID objectID, UUID regionUUID) + { + _Log.InfoFormat("[MSSQL]: Removing obj: {0} from region: {1}", objectID, regionUUID); + + //Remove from prims and primsitem table + string sqlPrims = "DELETE FROM PRIMS WHERE SceneGroupID = @objectID"; + string sqlPrimItems = "DELETE FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE SceneGroupID = @objectID)"; + string sqlPrimShapes = "DELETE FROM PRIMSHAPES WHERE uuid in (SELECT UUID FROM PRIMS WHERE SceneGroupID = @objectID)"; + + lock (_Database) + { + //Using the non transaction mode. + using (AutoClosingSqlCommand cmd = _Database.Query(sqlPrimShapes)) + { + cmd.Parameters.Add(_Database.CreateParameter("objectID", objectID)); + cmd.ExecuteNonQuery(); + + cmd.CommandText = sqlPrimItems; + cmd.ExecuteNonQuery(); + + cmd.CommandText = sqlPrims; + cmd.ExecuteNonQuery(); + } + } + } + + /// + /// Store the inventory of a prim. Warning deletes everything first and then adds all again. + /// + /// + /// + public void StorePrimInventory(UUID primID, ICollection items) + { + //_Log.InfoFormat("[REGION DB: Persisting Prim Inventory with prim ID {0}", primID); + + //Statement from MySQL section! + // For now, we're just going to crudely remove all the previous inventory items + // no matter whether they have changed or not, and replace them with the current set. + + //Delete everything from PrimID + //TODO add index on PrimID in DB, if not already exist + using (AutoClosingSqlCommand cmd = _Database.Query("DELETE PRIMITEMS WHERE primID = @primID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@primID", primID)); + cmd.ExecuteNonQuery(); + } + + string sql = + @"INSERT INTO primitems ( + itemID,primID,assetID,parentFolderID,invType,assetType,name,description,creationDate,creatorID,ownerID,lastOwnerID,groupID, + nextPermissions,currentPermissions,basePermissions,everyonePermissions,groupPermissions,flags) + VALUES (@itemID,@primID,@assetID,@parentFolderID,@invType,@assetType,@name,@description,@creationDate,@creatorID,@ownerID, + @lastOwnerID,@groupID,@nextPermissions,@currentPermissions,@basePermissions,@everyonePermissions,@groupPermissions,@flags)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + foreach (TaskInventoryItem taskItem in items) + { + cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem)); + cmd.ExecuteNonQuery(); + + cmd.Parameters.Clear(); + } + } + } + + #endregion + + /// + /// Loads the terrain map. + /// + /// regionID. + /// + public double[,] LoadTerrain(UUID regionID) + { + double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; + terrain.Initialize(); + + string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + // MySqlParameter param = new MySqlParameter(); + cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); + + using (SqlDataReader reader = cmd.ExecuteReader()) + { + int rev; + if (reader.Read()) + { + MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); + BinaryReader br = new BinaryReader(str); + for (int x = 0; x < (int)Constants.RegionSize; x++) + { + for (int y = 0; y < (int)Constants.RegionSize; y++) + { + terrain[x, y] = br.ReadDouble(); + } + } + rev = (int)reader["Revision"]; + } + else + { + _Log.Info("[REGION DB]: No terrain found for region"); + return null; + } + _Log.Info("[REGION DB]: Loaded terrain revision r" + rev); + } + } + + return terrain; + } + + /// + /// Stores the terrain map to DB. + /// + /// terrain map data. + /// regionID. + public void StoreTerrain(double[,] terrain, UUID regionID) + { + int revision = Util.UnixTimeSinceEpoch(); + + //Delete old terrain map + string sql = "delete from terrain where RegionUUID=@RegionUUID"; + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); + cmd.ExecuteNonQuery(); + } + + sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); + cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision)); + cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain))); + cmd.ExecuteNonQuery(); + } + + _Log.Info("[REGION DB]: Stored terrain revision r " + revision); + } + + /// + /// Loads all the land objects of a region. + /// + /// The region UUID. + /// + public List LoadLandObjects(UUID regionUUID) + { + List landDataForRegion = new List(); + + string sql = "select * from land where RegionUUID = @RegionUUID"; + + //Retrieve all land data from region + using (AutoClosingSqlCommand cmdLandData = _Database.Query(sql)) + { + cmdLandData.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionUUID)); + + using (SqlDataReader readerLandData = cmdLandData.ExecuteReader()) + { + while (readerLandData.Read()) + { + landDataForRegion.Add(BuildLandData(readerLandData)); + } + } + } + + //Retrieve all accesslist data for all landdata + foreach (LandData landData in landDataForRegion) + { + sql = "select * from landaccesslist where LandUUID = @LandUUID"; + using (AutoClosingSqlCommand cmdAccessList = _Database.Query(sql)) + { + cmdAccessList.Parameters.Add(_Database.CreateParameter("@LandUUID", landData.GlobalID)); + using (SqlDataReader readerAccessList = cmdAccessList.ExecuteReader()) + { + while (readerAccessList.Read()) + { + landData.ParcelAccessList.Add(BuildLandAccessData(readerAccessList)); + } + } + } + } + + //Return data + return landDataForRegion; + } + + /// + /// Stores land object with landaccess list. + /// + /// parcel data. + public void StoreLandObject(ILandObject parcel) + { + //As this is only one record in land table I just delete all and then add a new record. + //As the delete landaccess is already in the mysql code + + //Delete old values + RemoveLandObject(parcel.landData.GlobalID); + + //Insert new values + string sql = @"INSERT INTO [land] +([UUID],[RegionUUID],[LocalLandID],[Bitmap],[Name],[Description],[OwnerUUID],[IsGroupOwned],[Area],[AuctionID],[Category],[ClaimDate],[ClaimPrice],[GroupUUID],[SalePrice],[LandStatus],[LandFlags],[LandingType],[MediaAutoScale],[MediaTextureUUID],[MediaURL],[MusicURL],[PassHours],[PassPrice],[SnapshotUUID],[UserLocationX],[UserLocationY],[UserLocationZ],[UserLookAtX],[UserLookAtY],[UserLookAtZ],[AuthbuyerID],[OtherCleanTime],[Dwell]) +VALUES +(@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID,@OtherCleanTime,@Dwell)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddRange(CreateLandParameters(parcel.landData, parcel.regionUUID)); + + cmd.ExecuteNonQuery(); + } + + sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.landData.ParcelAccessList) + { + cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.regionUUID)); + + cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + } + } + } + + /// + /// Removes a land object from DB. + /// + /// UUID of landobject + public void RemoveLandObject(UUID globalID) + { + using (AutoClosingSqlCommand cmd = _Database.Query("delete from land where UUID=@UUID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); + cmd.ExecuteNonQuery(); + } + + using (AutoClosingSqlCommand cmd = _Database.Query("delete from landaccesslist where LandUUID=@UUID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); + cmd.ExecuteNonQuery(); + } + } + + /// + /// Loads the settings of a region. + /// + /// The region UUID. + /// + public RegionSettings LoadRegionSettings(UUID regionUUID) + { + string sql = "select * from regionsettings where regionUUID = @regionUUID"; + RegionSettings regionSettings; + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); + using (SqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) + { + regionSettings = BuildRegionSettings(reader); + regionSettings.OnSave += StoreRegionSettings; + + return regionSettings; + } + } + } + + //If comes here then there is now region setting for that region + regionSettings = new RegionSettings(); + regionSettings.RegionUUID = regionUUID; + regionSettings.OnSave += StoreRegionSettings; + + //Store new values + StoreNewRegionSettings(regionSettings); + + return regionSettings; + } + + /// + /// Store region settings, need to check if the check is really necesary. If we can make something for creating new region. + /// + /// region settings. + public void StoreRegionSettings(RegionSettings regionSettings) + { + //Little check if regionUUID already exist in DB + string regionUUID; + using (AutoClosingSqlCommand cmd = _Database.Query("SELECT regionUUID FROM regionsettings WHERE regionUUID = @regionUUID")) + { + cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionSettings.RegionUUID)); + regionUUID = cmd.ExecuteScalar().ToString(); + } + + if (string.IsNullOrEmpty(regionUUID)) + { + StoreNewRegionSettings(regionSettings); + } + else + { + //This method only updates region settings!!! First call LoadRegionSettings to create new region settings in DB + string sql = + @"UPDATE [regionsettings] SET [block_terraform] = @block_terraform ,[block_fly] = @block_fly ,[allow_damage] = @allow_damage +,[restrict_pushing] = @restrict_pushing ,[allow_land_resell] = @allow_land_resell ,[allow_land_join_divide] = @allow_land_join_divide +,[block_show_in_search] = @block_show_in_search ,[agent_limit] = @agent_limit ,[object_bonus] = @object_bonus ,[maturity] = @maturity +,[disable_scripts] = @disable_scripts ,[disable_collisions] = @disable_collisions ,[disable_physics] = @disable_physics +,[terrain_texture_1] = @terrain_texture_1 ,[terrain_texture_2] = @terrain_texture_2 ,[terrain_texture_3] = @terrain_texture_3 +,[terrain_texture_4] = @terrain_texture_4 ,[elevation_1_nw] = @elevation_1_nw ,[elevation_2_nw] = @elevation_2_nw +,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se +,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit +,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position +,[covenant] = @covenant , [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id + WHERE [regionUUID] = @regionUUID"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); + + cmd.ExecuteNonQuery(); + } + } + } + + public void Shutdown() + { + //Not used?? + } + + #region Private Methods + + /// + /// Serializes the terrain data for storage in DB. + /// + /// terrain data + /// + private static Array serializeTerrain(double[,] val) + { + MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double)); + BinaryWriter bw = new BinaryWriter(str); + + // TODO: COMPATIBILITY - Add byte-order conversions + for (int x = 0; x < (int)Constants.RegionSize; x++) + for (int y = 0; y < (int)Constants.RegionSize; y++) + { + double height = val[x, y]; + if (height == 0.0) + height = double.Epsilon; + + bw.Write(height); + } + + return str.ToArray(); + } + + /// + /// Stores new regionsettings. + /// + /// The region settings. + private void StoreNewRegionSettings(RegionSettings regionSettings) + { + string sql = @"INSERT INTO [regionsettings] + ([regionUUID],[block_terraform],[block_fly],[allow_damage],[restrict_pushing],[allow_land_resell],[allow_land_join_divide], + [block_show_in_search],[agent_limit],[object_bonus],[maturity],[disable_scripts],[disable_collisions],[disable_physics], + [terrain_texture_1],[terrain_texture_2],[terrain_texture_3],[terrain_texture_4],[elevation_1_nw],[elevation_2_nw],[elevation_1_ne], + [elevation_2_ne],[elevation_1_se],[elevation_2_se],[elevation_1_sw],[elevation_2_sw],[water_height],[terrain_raise_limit], + [terrain_lower_limit],[use_estate_sun],[fixed_sun],[sun_position],[covenant],[sunvectorx], [sunvectory], [sunvectorz],[Sandbox], [loaded_creation_datetime], [loaded_creation_id] + ) + VALUES + (@regionUUID,@block_terraform,@block_fly,@allow_damage,@restrict_pushing,@allow_land_resell,@allow_land_join_divide, + @block_show_in_search,@agent_limit,@object_bonus,@maturity,@disable_scripts,@disable_collisions,@disable_physics, + @terrain_texture_1,@terrain_texture_2,@terrain_texture_3,@terrain_texture_4,@elevation_1_nw,@elevation_2_nw,@elevation_1_ne, + @elevation_2_ne,@elevation_1_se,@elevation_2_se,@elevation_1_sw,@elevation_2_sw,@water_height,@terrain_raise_limit, + @terrain_lower_limit,@use_estate_sun,@fixed_sun,@sun_position,@covenant,@sunvectorx,@sunvectory, @sunvectorz, @Sandbox, @loaded_creation_datetime, @loaded_creation_id)"; + + using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + { + cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); + cmd.ExecuteNonQuery(); + } + } + + #region Private DataRecord conversion methods + + /// + /// Builds the region settings from a datarecod. + /// + /// datarecord with regionsettings. + /// + private static RegionSettings BuildRegionSettings(IDataRecord row) + { + //TODO change this is some more generic code so we doesnt have to change it every time a new field is added? + RegionSettings newSettings = new RegionSettings(); + + newSettings.RegionUUID = new UUID((Guid)row["regionUUID"]); + newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); + newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); + newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); + newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); + newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); + newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); + newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); + newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); + newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); + newSettings.Maturity = Convert.ToInt32(row["maturity"]); + newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); + newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); + newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); + newSettings.TerrainTexture1 = new UUID((Guid)row["terrain_texture_1"]); + newSettings.TerrainTexture2 = new UUID((Guid)row["terrain_texture_2"]); + newSettings.TerrainTexture3 = new UUID((Guid)row["terrain_texture_3"]); + newSettings.TerrainTexture4 = new UUID((Guid)row["terrain_texture_4"]); + newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); + newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); + newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); + newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); + newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); + newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); + newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); + newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); + newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); + newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); + newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); + newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); + newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]); + newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); + newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); + newSettings.SunVector = new Vector3( + Convert.ToSingle(row["sunvectorx"]), + Convert.ToSingle(row["sunvectory"]), + Convert.ToSingle(row["sunvectorz"]) + ); + newSettings.Covenant = new UUID((Guid)row["covenant"]); + + newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]); + + if (row["loaded_creation_id"] is DBNull) + newSettings.LoadedCreationID = ""; + else + newSettings.LoadedCreationID = (String)row["loaded_creation_id"]; + return newSettings; + } + + /// + /// Builds the land data from a datarecord. + /// + /// datarecord with land data + /// + private static LandData BuildLandData(IDataRecord row) + { + LandData newData = new LandData(); + + newData.GlobalID = new UUID((Guid)row["UUID"]); + newData.LocalID = Convert.ToInt32(row["LocalLandID"]); + + // Bitmap is a byte[512] + newData.Bitmap = (Byte[])row["Bitmap"]; + + newData.Name = (string)row["Name"]; + newData.Description = (string)row["Description"]; + newData.OwnerID = new UUID((Guid)row["OwnerUUID"]); + newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); + newData.Area = Convert.ToInt32(row["Area"]); + newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented + newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]); + //Enum libsecondlife.Parcel.ParcelCategory + newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); + newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); + newData.GroupID = new UUID((Guid)row["GroupUUID"]); + newData.SalePrice = Convert.ToInt32(row["SalePrice"]); + newData.Status = (ParcelStatus)Convert.ToInt32(row["LandStatus"]); + //Enum. libsecondlife.Parcel.ParcelStatus + newData.Flags = Convert.ToUInt32(row["LandFlags"]); + newData.LandingType = Convert.ToByte(row["LandingType"]); + newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); + newData.MediaID = new UUID((Guid)row["MediaTextureUUID"]); + newData.MediaURL = (string)row["MediaURL"]; + newData.MusicURL = (string)row["MusicURL"]; + newData.PassHours = Convert.ToSingle(row["PassHours"]); + newData.PassPrice = Convert.ToInt32(row["PassPrice"]); + +// UUID authedbuyer; +// UUID snapshotID; +// +// if (UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer)) +// newData.AuthBuyerID = authedbuyer; +// +// if (UUID.TryParse((string)row["SnapshotUUID"], out snapshotID)) +// newData.SnapshotID = snapshotID; + newData.AuthBuyerID = new UUID((Guid) row["AuthBuyerID"]); + newData.SnapshotID = new UUID((Guid)row["SnapshotUUID"]); + + newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); + newData.Dwell = Convert.ToInt32(row["Dwell"]); + + try + { + newData.UserLocation = + new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), + Convert.ToSingle(row["UserLocationZ"])); + newData.UserLookAt = + new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), + Convert.ToSingle(row["UserLookAtZ"])); + } + catch (InvalidCastException) + { + newData.UserLocation = Vector3.Zero; + newData.UserLookAt = Vector3.Zero; + _Log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); + } + + newData.ParcelAccessList = new List(); + + return newData; + } + + /// + /// Builds the landaccess data from a data record. + /// + /// datarecord with landaccess data + /// + private static ParcelManager.ParcelAccessEntry BuildLandAccessData(IDataRecord row) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = new UUID((Guid)row["AccessUUID"]); + entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]); + entry.Time = new DateTime(); + return entry; + } + + /// + /// Builds the prim from a datarecord. + /// + /// datarecord + /// + private static SceneObjectPart BuildPrim(IDataRecord primRow) + { + SceneObjectPart prim = new SceneObjectPart(); + + prim.UUID = new UUID((Guid)primRow["UUID"]); + // explicit conversion of integers is required, which sort + // of sucks. No idea if there is a shortcut here or not. + prim.CreationDate = Convert.ToInt32(primRow["CreationDate"]); + prim.Name = (string)primRow["Name"]; + // various text fields + prim.Text = (string)primRow["Text"]; + prim.Color = Color.FromArgb(Convert.ToInt32(primRow["ColorA"]), + Convert.ToInt32(primRow["ColorR"]), + Convert.ToInt32(primRow["ColorG"]), + Convert.ToInt32(primRow["ColorB"])); + prim.Description = (string)primRow["Description"]; + prim.SitName = (string)primRow["SitName"]; + prim.TouchName = (string)primRow["TouchName"]; + // permissions + prim.ObjectFlags = Convert.ToUInt32(primRow["ObjectFlags"]); + prim.CreatorID = new UUID((Guid)primRow["CreatorID"]); + prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); + prim.GroupID = new UUID((Guid)primRow["GroupID"]); + prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); + prim.OwnerMask = Convert.ToUInt32(primRow["OwnerMask"]); + prim.NextOwnerMask = Convert.ToUInt32(primRow["NextOwnerMask"]); + prim.GroupMask = Convert.ToUInt32(primRow["GroupMask"]); + prim.EveryoneMask = Convert.ToUInt32(primRow["EveryoneMask"]); + prim.BaseMask = Convert.ToUInt32(primRow["BaseMask"]); + // vectors + prim.OffsetPosition = new Vector3( + Convert.ToSingle(primRow["PositionX"]), + Convert.ToSingle(primRow["PositionY"]), + Convert.ToSingle(primRow["PositionZ"])); + + prim.GroupPosition = new Vector3( + Convert.ToSingle(primRow["GroupPositionX"]), + Convert.ToSingle(primRow["GroupPositionY"]), + Convert.ToSingle(primRow["GroupPositionZ"])); + + prim.Velocity = new Vector3( + Convert.ToSingle(primRow["VelocityX"]), + Convert.ToSingle(primRow["VelocityY"]), + Convert.ToSingle(primRow["VelocityZ"])); + + prim.AngularVelocity = new Vector3( + Convert.ToSingle(primRow["AngularVelocityX"]), + Convert.ToSingle(primRow["AngularVelocityY"]), + Convert.ToSingle(primRow["AngularVelocityZ"])); + + prim.Acceleration = new Vector3( + Convert.ToSingle(primRow["AccelerationX"]), + Convert.ToSingle(primRow["AccelerationY"]), + Convert.ToSingle(primRow["AccelerationZ"])); + + // quaternions + prim.RotationOffset = new Quaternion( + Convert.ToSingle(primRow["RotationX"]), + Convert.ToSingle(primRow["RotationY"]), + Convert.ToSingle(primRow["RotationZ"]), + Convert.ToSingle(primRow["RotationW"])); + + prim.SitTargetPositionLL = new Vector3( + Convert.ToSingle(primRow["SitTargetOffsetX"]), + Convert.ToSingle(primRow["SitTargetOffsetY"]), + Convert.ToSingle(primRow["SitTargetOffsetZ"])); + + prim.SitTargetOrientationLL = new Quaternion( + Convert.ToSingle(primRow["SitTargetOrientX"]), + Convert.ToSingle(primRow["SitTargetOrientY"]), + Convert.ToSingle(primRow["SitTargetOrientZ"]), + Convert.ToSingle(primRow["SitTargetOrientW"])); + + prim.PayPrice[0] = Convert.ToInt32(primRow["PayPrice"]); + prim.PayPrice[1] = Convert.ToInt32(primRow["PayButton1"]); + prim.PayPrice[2] = Convert.ToInt32(primRow["PayButton2"]); + prim.PayPrice[3] = Convert.ToInt32(primRow["PayButton3"]); + prim.PayPrice[4] = Convert.ToInt32(primRow["PayButton4"]); + + prim.Sound = new UUID((Guid)primRow["LoopedSound"]); + prim.SoundGain = Convert.ToSingle(primRow["LoopedSoundGain"]); + prim.SoundFlags = 1; // If it's persisted at all, it's looped + + if (!(primRow["TextureAnimation"] is DBNull)) + prim.TextureAnimation = (Byte[])primRow["TextureAnimation"]; + if (!(primRow["ParticleSystem"] is DBNull)) + prim.ParticleSystem = (Byte[])primRow["ParticleSystem"]; + + prim.RotationalVelocity = new Vector3( + Convert.ToSingle(primRow["OmegaX"]), + Convert.ToSingle(primRow["OmegaY"]), + Convert.ToSingle(primRow["OmegaZ"])); + + prim.SetCameraEyeOffset(new Vector3( + Convert.ToSingle(primRow["CameraEyeOffsetX"]), + Convert.ToSingle(primRow["CameraEyeOffsetY"]), + Convert.ToSingle(primRow["CameraEyeOffsetZ"]) + )); + + prim.SetCameraAtOffset(new Vector3( + Convert.ToSingle(primRow["CameraAtOffsetX"]), + Convert.ToSingle(primRow["CameraAtOffsetY"]), + Convert.ToSingle(primRow["CameraAtOffsetZ"]) + )); + + if (Convert.ToInt16(primRow["ForceMouselook"]) != 0) + prim.SetForceMouselook(true); + + prim.ScriptAccessPin = Convert.ToInt32(primRow["ScriptAccessPin"]); + + if (Convert.ToInt16(primRow["AllowedDrop"]) != 0) + prim.AllowedDrop = true; + + if (Convert.ToInt16(primRow["DieAtEdge"]) != 0) + prim.DIE_AT_EDGE = true; + + prim.SalePrice = Convert.ToInt32(primRow["SalePrice"]); + prim.ObjectSaleType = Convert.ToByte(primRow["SaleType"]); + + prim.Material = Convert.ToByte(primRow["Material"]); + + if (!(primRow["ClickAction"] is DBNull)) + prim.ClickAction = Convert.ToByte(primRow["ClickAction"]); + + prim.CollisionSound = new UUID((Guid)primRow["CollisionSound"]); + prim.CollisionSoundVolume = Convert.ToSingle(primRow["CollisionSoundVolume"]); + if (Convert.ToInt16(primRow["PassTouches"]) != 0) + prim.PassTouches = true; + prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); + + return prim; + } + + /// + /// Builds the prim shape from a datarecord. + /// + /// The row. + /// + private static PrimitiveBaseShape BuildShape(IDataRecord shapeRow) + { + PrimitiveBaseShape baseShape = new PrimitiveBaseShape(); + + baseShape.Scale = new Vector3( + Convert.ToSingle(shapeRow["ScaleX"]), + Convert.ToSingle(shapeRow["ScaleY"]), + Convert.ToSingle(shapeRow["ScaleZ"])); + + // paths + baseShape.PCode = Convert.ToByte(shapeRow["PCode"]); + baseShape.PathBegin = Convert.ToUInt16(shapeRow["PathBegin"]); + baseShape.PathEnd = Convert.ToUInt16(shapeRow["PathEnd"]); + baseShape.PathScaleX = Convert.ToByte(shapeRow["PathScaleX"]); + baseShape.PathScaleY = Convert.ToByte(shapeRow["PathScaleY"]); + baseShape.PathShearX = Convert.ToByte(shapeRow["PathShearX"]); + baseShape.PathShearY = Convert.ToByte(shapeRow["PathShearY"]); + baseShape.PathSkew = Convert.ToSByte(shapeRow["PathSkew"]); + baseShape.PathCurve = Convert.ToByte(shapeRow["PathCurve"]); + baseShape.PathRadiusOffset = Convert.ToSByte(shapeRow["PathRadiusOffset"]); + baseShape.PathRevolutions = Convert.ToByte(shapeRow["PathRevolutions"]); + baseShape.PathTaperX = Convert.ToSByte(shapeRow["PathTaperX"]); + baseShape.PathTaperY = Convert.ToSByte(shapeRow["PathTaperY"]); + baseShape.PathTwist = Convert.ToSByte(shapeRow["PathTwist"]); + baseShape.PathTwistBegin = Convert.ToSByte(shapeRow["PathTwistBegin"]); + // profile + baseShape.ProfileBegin = Convert.ToUInt16(shapeRow["ProfileBegin"]); + baseShape.ProfileEnd = Convert.ToUInt16(shapeRow["ProfileEnd"]); + baseShape.ProfileCurve = Convert.ToByte(shapeRow["ProfileCurve"]); + baseShape.ProfileHollow = Convert.ToUInt16(shapeRow["ProfileHollow"]); + + byte[] textureEntry = (byte[])shapeRow["Texture"]; + baseShape.TextureEntry = textureEntry; + + baseShape.ExtraParams = (byte[])shapeRow["ExtraParams"]; + + try + { + baseShape.State = Convert.ToByte(shapeRow["State"]); + } + catch (InvalidCastException) + { + } + + return baseShape; + } + + /// + /// Build a prim inventory item from the persisted data. + /// + /// + /// + private static TaskInventoryItem BuildItem(IDataRecord inventoryRow) + { + TaskInventoryItem taskItem = new TaskInventoryItem(); + + taskItem.ItemID = new UUID((Guid)inventoryRow["itemID"]); + taskItem.ParentPartID = new UUID((Guid)inventoryRow["primID"]); + taskItem.AssetID = new UUID((Guid)inventoryRow["assetID"]); + taskItem.ParentID = new UUID((Guid)inventoryRow["parentFolderID"]); + + taskItem.InvType = Convert.ToInt32(inventoryRow["invType"]); + taskItem.Type = Convert.ToInt32(inventoryRow["assetType"]); + + taskItem.Name = (string)inventoryRow["name"]; + taskItem.Description = (string)inventoryRow["description"]; + taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]); + taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]); + taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]); + taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]); + taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]); + + taskItem.NextPermissions = Convert.ToUInt32(inventoryRow["nextPermissions"]); + taskItem.CurrentPermissions = Convert.ToUInt32(inventoryRow["currentPermissions"]); + taskItem.BasePermissions = Convert.ToUInt32(inventoryRow["basePermissions"]); + taskItem.EveryonePermissions = Convert.ToUInt32(inventoryRow["everyonePermissions"]); + taskItem.GroupPermissions = Convert.ToUInt32(inventoryRow["groupPermissions"]); + taskItem.Flags = Convert.ToUInt32(inventoryRow["flags"]); + + return taskItem; + } + + #endregion + + #region Create parameters methods + + /// + /// Creates the prim inventory parameters. + /// + /// item in inventory. + /// + private SqlParameter[] CreatePrimInventoryParameters(TaskInventoryItem taskItem) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("itemID", taskItem.ItemID)); + parameters.Add(_Database.CreateParameter("primID", taskItem.ParentPartID)); + parameters.Add(_Database.CreateParameter("assetID", taskItem.AssetID)); + parameters.Add(_Database.CreateParameter("parentFolderID", taskItem.ParentID)); + parameters.Add(_Database.CreateParameter("invType", taskItem.InvType)); + parameters.Add(_Database.CreateParameter("assetType", taskItem.Type)); + + parameters.Add(_Database.CreateParameter("name", taskItem.Name)); + parameters.Add(_Database.CreateParameter("description", taskItem.Description)); + parameters.Add(_Database.CreateParameter("creationDate", taskItem.CreationDate)); + parameters.Add(_Database.CreateParameter("creatorID", taskItem.CreatorID)); + parameters.Add(_Database.CreateParameter("ownerID", taskItem.OwnerID)); + parameters.Add(_Database.CreateParameter("lastOwnerID", taskItem.LastOwnerID)); + parameters.Add(_Database.CreateParameter("groupID", taskItem.GroupID)); + parameters.Add(_Database.CreateParameter("nextPermissions", taskItem.NextPermissions)); + parameters.Add(_Database.CreateParameter("currentPermissions", taskItem.CurrentPermissions)); + parameters.Add(_Database.CreateParameter("basePermissions", taskItem.BasePermissions)); + parameters.Add(_Database.CreateParameter("everyonePermissions", taskItem.EveryonePermissions)); + parameters.Add(_Database.CreateParameter("groupPermissions", taskItem.GroupPermissions)); + parameters.Add(_Database.CreateParameter("flags", taskItem.Flags)); + + return parameters.ToArray(); + } + + /// + /// Creates the region setting parameters. + /// + /// regionsettings. + /// + private SqlParameter[] CreateRegionSettingParameters(RegionSettings settings) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("regionUUID", settings.RegionUUID)); + parameters.Add(_Database.CreateParameter("block_terraform", settings.BlockTerraform)); + parameters.Add(_Database.CreateParameter("block_fly", settings.BlockFly)); + parameters.Add(_Database.CreateParameter("allow_damage", settings.AllowDamage)); + parameters.Add(_Database.CreateParameter("restrict_pushing", settings.RestrictPushing)); + parameters.Add(_Database.CreateParameter("allow_land_resell", settings.AllowLandResell)); + parameters.Add(_Database.CreateParameter("allow_land_join_divide", settings.AllowLandJoinDivide)); + parameters.Add(_Database.CreateParameter("block_show_in_search", settings.BlockShowInSearch)); + parameters.Add(_Database.CreateParameter("agent_limit", settings.AgentLimit)); + parameters.Add(_Database.CreateParameter("object_bonus", settings.ObjectBonus)); + parameters.Add(_Database.CreateParameter("maturity", settings.Maturity)); + parameters.Add(_Database.CreateParameter("disable_scripts", settings.DisableScripts)); + parameters.Add(_Database.CreateParameter("disable_collisions", settings.DisableCollisions)); + parameters.Add(_Database.CreateParameter("disable_physics", settings.DisablePhysics)); + parameters.Add(_Database.CreateParameter("terrain_texture_1", settings.TerrainTexture1)); + parameters.Add(_Database.CreateParameter("terrain_texture_2", settings.TerrainTexture2)); + parameters.Add(_Database.CreateParameter("terrain_texture_3", settings.TerrainTexture3)); + parameters.Add(_Database.CreateParameter("terrain_texture_4", settings.TerrainTexture4)); + parameters.Add(_Database.CreateParameter("elevation_1_nw", settings.Elevation1NW)); + parameters.Add(_Database.CreateParameter("elevation_2_nw", settings.Elevation2NW)); + parameters.Add(_Database.CreateParameter("elevation_1_ne", settings.Elevation1NE)); + parameters.Add(_Database.CreateParameter("elevation_2_ne", settings.Elevation2NE)); + parameters.Add(_Database.CreateParameter("elevation_1_se", settings.Elevation1SE)); + parameters.Add(_Database.CreateParameter("elevation_2_se", settings.Elevation2SE)); + parameters.Add(_Database.CreateParameter("elevation_1_sw", settings.Elevation1SW)); + parameters.Add(_Database.CreateParameter("elevation_2_sw", settings.Elevation2SW)); + parameters.Add(_Database.CreateParameter("water_height", settings.WaterHeight)); + parameters.Add(_Database.CreateParameter("terrain_raise_limit", settings.TerrainRaiseLimit)); + parameters.Add(_Database.CreateParameter("terrain_lower_limit", settings.TerrainLowerLimit)); + parameters.Add(_Database.CreateParameter("use_estate_sun", settings.UseEstateSun)); + parameters.Add(_Database.CreateParameter("sandbox", settings.Sandbox)); + parameters.Add(_Database.CreateParameter("fixed_sun", settings.FixedSun)); + parameters.Add(_Database.CreateParameter("sun_position", settings.SunPosition)); + parameters.Add(_Database.CreateParameter("sunvectorx", settings.SunVector.X)); + parameters.Add(_Database.CreateParameter("sunvectory", settings.SunVector.Y)); + parameters.Add(_Database.CreateParameter("sunvectorz", settings.SunVector.Z)); + parameters.Add(_Database.CreateParameter("covenant", settings.Covenant)); + parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime)); + parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID)); + + return parameters.ToArray(); + } + + /// + /// Creates the land parameters. + /// + /// land parameters. + /// region UUID. + /// + private SqlParameter[] CreateLandParameters(LandData land, UUID regionUUID) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("UUID", land.GlobalID)); + parameters.Add(_Database.CreateParameter("RegionUUID", regionUUID)); + parameters.Add(_Database.CreateParameter("LocalLandID", land.LocalID)); + + // Bitmap is a byte[512] + parameters.Add(_Database.CreateParameter("Bitmap", land.Bitmap)); + + parameters.Add(_Database.CreateParameter("Name", land.Name)); + parameters.Add(_Database.CreateParameter("Description", land.Description)); + parameters.Add(_Database.CreateParameter("OwnerUUID", land.OwnerID)); + parameters.Add(_Database.CreateParameter("IsGroupOwned", land.IsGroupOwned)); + parameters.Add(_Database.CreateParameter("Area", land.Area)); + parameters.Add(_Database.CreateParameter("AuctionID", land.AuctionID)); //Unemplemented + parameters.Add(_Database.CreateParameter("Category", (int)land.Category)); //Enum libsecondlife.Parcel.ParcelCategory + parameters.Add(_Database.CreateParameter("ClaimDate", land.ClaimDate)); + parameters.Add(_Database.CreateParameter("ClaimPrice", land.ClaimPrice)); + parameters.Add(_Database.CreateParameter("GroupUUID", land.GroupID)); + parameters.Add(_Database.CreateParameter("SalePrice", land.SalePrice)); + parameters.Add(_Database.CreateParameter("LandStatus", (int)land.Status)); //Enum. libsecondlife.Parcel.ParcelStatus + parameters.Add(_Database.CreateParameter("LandFlags", land.Flags)); + parameters.Add(_Database.CreateParameter("LandingType", land.LandingType)); + parameters.Add(_Database.CreateParameter("MediaAutoScale", land.MediaAutoScale)); + parameters.Add(_Database.CreateParameter("MediaTextureUUID", land.MediaID)); + parameters.Add(_Database.CreateParameter("MediaURL", land.MediaURL)); + parameters.Add(_Database.CreateParameter("MusicURL", land.MusicURL)); + parameters.Add(_Database.CreateParameter("PassHours", land.PassHours)); + parameters.Add(_Database.CreateParameter("PassPrice", land.PassPrice)); + parameters.Add(_Database.CreateParameter("SnapshotUUID", land.SnapshotID)); + parameters.Add(_Database.CreateParameter("UserLocationX", land.UserLocation.X)); + parameters.Add(_Database.CreateParameter("UserLocationY", land.UserLocation.Y)); + parameters.Add(_Database.CreateParameter("UserLocationZ", land.UserLocation.Z)); + parameters.Add(_Database.CreateParameter("UserLookAtX", land.UserLookAt.X)); + parameters.Add(_Database.CreateParameter("UserLookAtY", land.UserLookAt.Y)); + parameters.Add(_Database.CreateParameter("UserLookAtZ", land.UserLookAt.Z)); + parameters.Add(_Database.CreateParameter("AuthBuyerID", land.AuthBuyerID)); + parameters.Add(_Database.CreateParameter("OtherCleanTime", land.OtherCleanTime)); + parameters.Add(_Database.CreateParameter("Dwell", land.Dwell)); + + return parameters.ToArray(); + } + + /// + /// Creates the land access parameters. + /// + /// parcel access entry. + /// parcel ID. + /// + private SqlParameter[] CreateLandAccessParameters(ParcelManager.ParcelAccessEntry parcelAccessEntry, UUID parcelID) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("LandUUID", parcelID)); + parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID)); + parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags)); + + return parameters.ToArray(); + } + + /// + /// Creates the prim parameters for storing in DB. + /// + /// Basic data of SceneObjectpart prim. + /// The scenegroup ID. + /// The region ID. + /// + private SqlParameter[] CreatePrimParameters(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) + { + List parameters = new List(); + + parameters.Add(_Database.CreateParameter("UUID", prim.UUID)); + parameters.Add(_Database.CreateParameter("RegionUUID", regionUUID)); + parameters.Add(_Database.CreateParameter("CreationDate", prim.CreationDate)); + parameters.Add(_Database.CreateParameter("Name", prim.Name)); + parameters.Add(_Database.CreateParameter("SceneGroupID", sceneGroupID)); + // the UUID of the root part for this SceneObjectGroup + // various text fields + parameters.Add(_Database.CreateParameter("Text", prim.Text)); + parameters.Add(_Database.CreateParameter("ColorR", prim.Color.R)); + parameters.Add(_Database.CreateParameter("ColorG", prim.Color.G)); + parameters.Add(_Database.CreateParameter("ColorB", prim.Color.B)); + parameters.Add(_Database.CreateParameter("ColorA", prim.Color.A)); + parameters.Add(_Database.CreateParameter("Description", prim.Description)); + parameters.Add(_Database.CreateParameter("SitName", prim.SitName)); + parameters.Add(_Database.CreateParameter("TouchName", prim.TouchName)); + // permissions + parameters.Add(_Database.CreateParameter("ObjectFlags", prim.ObjectFlags)); + parameters.Add(_Database.CreateParameter("CreatorID", prim.CreatorID)); + parameters.Add(_Database.CreateParameter("OwnerID", prim.OwnerID)); + parameters.Add(_Database.CreateParameter("GroupID", prim.GroupID)); + parameters.Add(_Database.CreateParameter("LastOwnerID", prim.LastOwnerID)); + parameters.Add(_Database.CreateParameter("OwnerMask", prim.OwnerMask)); + parameters.Add(_Database.CreateParameter("NextOwnerMask", prim.NextOwnerMask)); + parameters.Add(_Database.CreateParameter("GroupMask", prim.GroupMask)); + parameters.Add(_Database.CreateParameter("EveryoneMask", prim.EveryoneMask)); + parameters.Add(_Database.CreateParameter("BaseMask", prim.BaseMask)); + // vectors + parameters.Add(_Database.CreateParameter("PositionX", prim.OffsetPosition.X)); + parameters.Add(_Database.CreateParameter("PositionY", prim.OffsetPosition.Y)); + parameters.Add(_Database.CreateParameter("PositionZ", prim.OffsetPosition.Z)); + parameters.Add(_Database.CreateParameter("GroupPositionX", prim.GroupPosition.X)); + parameters.Add(_Database.CreateParameter("GroupPositionY", prim.GroupPosition.Y)); + parameters.Add(_Database.CreateParameter("GroupPositionZ", prim.GroupPosition.Z)); + parameters.Add(_Database.CreateParameter("VelocityX", prim.Velocity.X)); + parameters.Add(_Database.CreateParameter("VelocityY", prim.Velocity.Y)); + parameters.Add(_Database.CreateParameter("VelocityZ", prim.Velocity.Z)); + parameters.Add(_Database.CreateParameter("AngularVelocityX", prim.AngularVelocity.X)); + parameters.Add(_Database.CreateParameter("AngularVelocityY", prim.AngularVelocity.Y)); + parameters.Add(_Database.CreateParameter("AngularVelocityZ", prim.AngularVelocity.Z)); + parameters.Add(_Database.CreateParameter("AccelerationX", prim.Acceleration.X)); + parameters.Add(_Database.CreateParameter("AccelerationY", prim.Acceleration.Y)); + parameters.Add(_Database.CreateParameter("AccelerationZ", prim.Acceleration.Z)); + // quaternions + parameters.Add(_Database.CreateParameter("RotationX", prim.RotationOffset.X)); + parameters.Add(_Database.CreateParameter("RotationY", prim.RotationOffset.Y)); + parameters.Add(_Database.CreateParameter("RotationZ", prim.RotationOffset.Z)); + parameters.Add(_Database.CreateParameter("RotationW", prim.RotationOffset.W)); + + // Sit target + Vector3 sitTargetPos = prim.SitTargetPositionLL; + parameters.Add(_Database.CreateParameter("SitTargetOffsetX", sitTargetPos.X)); + parameters.Add(_Database.CreateParameter("SitTargetOffsetY", sitTargetPos.Y)); + parameters.Add(_Database.CreateParameter("SitTargetOffsetZ", sitTargetPos.Z)); + + Quaternion sitTargetOrient = prim.SitTargetOrientationLL; + parameters.Add(_Database.CreateParameter("SitTargetOrientW", sitTargetOrient.W)); + parameters.Add(_Database.CreateParameter("SitTargetOrientX", sitTargetOrient.X)); + parameters.Add(_Database.CreateParameter("SitTargetOrientY", sitTargetOrient.Y)); + parameters.Add(_Database.CreateParameter("SitTargetOrientZ", sitTargetOrient.Z)); + + parameters.Add(_Database.CreateParameter("PayPrice", prim.PayPrice[0])); + parameters.Add(_Database.CreateParameter("PayButton1", prim.PayPrice[1])); + parameters.Add(_Database.CreateParameter("PayButton2", prim.PayPrice[2])); + parameters.Add(_Database.CreateParameter("PayButton3", prim.PayPrice[3])); + parameters.Add(_Database.CreateParameter("PayButton4", prim.PayPrice[4])); + + if ((prim.SoundFlags & 1) != 0) // Looped + { + parameters.Add(_Database.CreateParameter("LoopedSound", prim.Sound)); + parameters.Add(_Database.CreateParameter("LoopedSoundGain", prim.SoundGain)); + } + else + { + parameters.Add(_Database.CreateParameter("LoopedSound", UUID.Zero)); + parameters.Add(_Database.CreateParameter("LoopedSoundGain", 0.0f)); + } + + parameters.Add(_Database.CreateParameter("TextureAnimation", prim.TextureAnimation)); + parameters.Add(_Database.CreateParameter("ParticleSystem", prim.ParticleSystem)); + + parameters.Add(_Database.CreateParameter("OmegaX", prim.RotationalVelocity.X)); + parameters.Add(_Database.CreateParameter("OmegaY", prim.RotationalVelocity.Y)); + parameters.Add(_Database.CreateParameter("OmegaZ", prim.RotationalVelocity.Z)); + + parameters.Add(_Database.CreateParameter("CameraEyeOffsetX", prim.GetCameraEyeOffset().X)); + parameters.Add(_Database.CreateParameter("CameraEyeOffsetY", prim.GetCameraEyeOffset().Y)); + parameters.Add(_Database.CreateParameter("CameraEyeOffsetZ", prim.GetCameraEyeOffset().Z)); + + parameters.Add(_Database.CreateParameter("CameraAtOffsetX", prim.GetCameraAtOffset().X)); + parameters.Add(_Database.CreateParameter("CameraAtOffsetY", prim.GetCameraAtOffset().Y)); + parameters.Add(_Database.CreateParameter("CameraAtOffsetZ", prim.GetCameraAtOffset().Z)); + + if (prim.GetForceMouselook()) + parameters.Add(_Database.CreateParameter("ForceMouselook", 1)); + else + parameters.Add(_Database.CreateParameter("ForceMouselook", 0)); + + parameters.Add(_Database.CreateParameter("ScriptAccessPin", prim.ScriptAccessPin)); + + if (prim.AllowedDrop) + parameters.Add(_Database.CreateParameter("AllowedDrop", 1)); + else + parameters.Add(_Database.CreateParameter("AllowedDrop", 0)); + + if (prim.DIE_AT_EDGE) + parameters.Add(_Database.CreateParameter("DieAtEdge", 1)); + else + parameters.Add(_Database.CreateParameter("DieAtEdge", 0)); + + parameters.Add(_Database.CreateParameter("SalePrice", prim.SalePrice)); + parameters.Add(_Database.CreateParameter("SaleType", prim.ObjectSaleType)); + + byte clickAction = prim.ClickAction; + parameters.Add(_Database.CreateParameter("ClickAction", clickAction)); + + parameters.Add(_Database.CreateParameter("Material", prim.Material)); + + parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound)); + parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume)); + if (prim.PassTouches) + parameters.Add(_Database.CreateParameter("PassTouches", 1)); + else + parameters.Add(_Database.CreateParameter("PassTouches", 0)); + parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); + + return parameters.ToArray(); + } + + /// + /// Creates the primshape parameters for stroing in DB. + /// + /// Basic data of SceneObjectpart prim. + /// The scene group ID. + /// The region UUID. + /// + private SqlParameter[] CreatePrimShapeParameters(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) + { + List parameters = new List(); + + PrimitiveBaseShape s = prim.Shape; + parameters.Add(_Database.CreateParameter("UUID", prim.UUID)); + // shape is an enum + parameters.Add(_Database.CreateParameter("Shape", 0)); + // vectors + parameters.Add(_Database.CreateParameter("ScaleX", s.Scale.X)); + parameters.Add(_Database.CreateParameter("ScaleY", s.Scale.Y)); + parameters.Add(_Database.CreateParameter("ScaleZ", s.Scale.Z)); + // paths + parameters.Add(_Database.CreateParameter("PCode", s.PCode)); + parameters.Add(_Database.CreateParameter("PathBegin", s.PathBegin)); + parameters.Add(_Database.CreateParameter("PathEnd", s.PathEnd)); + parameters.Add(_Database.CreateParameter("PathScaleX", s.PathScaleX)); + parameters.Add(_Database.CreateParameter("PathScaleY", s.PathScaleY)); + parameters.Add(_Database.CreateParameter("PathShearX", s.PathShearX)); + parameters.Add(_Database.CreateParameter("PathShearY", s.PathShearY)); + parameters.Add(_Database.CreateParameter("PathSkew", s.PathSkew)); + parameters.Add(_Database.CreateParameter("PathCurve", s.PathCurve)); + parameters.Add(_Database.CreateParameter("PathRadiusOffset", s.PathRadiusOffset)); + parameters.Add(_Database.CreateParameter("PathRevolutions", s.PathRevolutions)); + parameters.Add(_Database.CreateParameter("PathTaperX", s.PathTaperX)); + parameters.Add(_Database.CreateParameter("PathTaperY", s.PathTaperY)); + parameters.Add(_Database.CreateParameter("PathTwist", s.PathTwist)); + parameters.Add(_Database.CreateParameter("PathTwistBegin", s.PathTwistBegin)); + // profile + parameters.Add(_Database.CreateParameter("ProfileBegin", s.ProfileBegin)); + parameters.Add(_Database.CreateParameter("ProfileEnd", s.ProfileEnd)); + parameters.Add(_Database.CreateParameter("ProfileCurve", s.ProfileCurve)); + parameters.Add(_Database.CreateParameter("ProfileHollow", s.ProfileHollow)); + parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry)); + parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); + parameters.Add(_Database.CreateParameter("State", s.State)); + + return parameters.ToArray(); + } + + #endregion + + #endregion + } +} diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index 6318c09..78d7fd0 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs @@ -13,7 +13,7 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY @@ -43,1489 +43,269 @@ namespace OpenSim.Data.MSSQL /// /// A MSSQL Interface for the Region Server. /// - public class MSSQLRegionDataStore : IRegionDataStore + public class MSSQLRegionData : IRegionData { - private const string _migrationStore = "RegionStore"; + private string m_Realm; + private List m_ColumnNames = null; + private string m_ConnectionString; + private MSSQLManager m_database; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - // private static FileSystemDataStore Instance = new FileSystemDataStore(); - private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// The database manager - /// - private MSSQLManager _Database; - - /// - /// Initialises the region datastore - /// - /// The connection string. - public void Initialise(string connectionString) + public MSSQLRegionData(string connectionString, string realm) { - if (!string.IsNullOrEmpty(connectionString)) - { - _Database = new MSSQLManager(connectionString); - } - else - { - IniFile iniFile = new IniFile("mssql_connection.ini"); - string settingDataSource = iniFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); - string settingUserId = iniFile.ParseFileReadValue("user_id"); - string settingPassword = iniFile.ParseFileReadValue("password"); - - _Database = new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, settingPassword); - } - - //Migration settings - _Database.CheckMigration(_migrationStore); - } - - /// - /// Dispose the database - /// - public void Dispose() { } - - #region SceneObjectGroup region for loading and Store of the scene. - - /// - /// Loads the objects present in the region. - /// - /// The region UUID. - /// - public List LoadObjects(UUID regionUUID) - { - UUID lastGroupID = UUID.Zero; - - Dictionary prims = new Dictionary(); - Dictionary objects = new Dictionary(); - SceneObjectGroup grp = null; - - - string query = "SELECT *, " + - "sort = CASE WHEN prims.UUID = prims.SceneGroupID THEN 0 ELSE 1 END " + - "FROM prims " + - "LEFT JOIN primshapes ON prims.UUID = primshapes.UUID " + - "WHERE RegionUUID = @RegionUUID " + - "ORDER BY SceneGroupID asc, sort asc, LinkNumber asc"; - - using (AutoClosingSqlCommand command = _Database.Query(query)) - { - command.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); - - using (SqlDataReader reader = command.ExecuteReader()) - { - while (reader.Read()) - { - SceneObjectPart sceneObjectPart = BuildPrim(reader); - if (reader["Shape"] is DBNull) - sceneObjectPart.Shape = PrimitiveBaseShape.Default; - else - sceneObjectPart.Shape = BuildShape(reader); - - prims[sceneObjectPart.UUID] = sceneObjectPart; - - UUID groupID = new UUID((Guid)reader["SceneGroupID"]); + m_Realm = realm; + m_ConnectionString = connectionString; + m_database = new MSSQLManager(connectionString); - if (groupID != lastGroupID) // New SOG - { - if (grp != null) - objects[grp.UUID] = grp; - - lastGroupID = groupID; - - // There sometimes exist OpenSim bugs that 'orphan groups' so that none of the prims are - // recorded as the root prim (for which the UUID must equal the persisted group UUID). In - // this case, force the UUID to be the same as the group UUID so that at least these can be - // deleted (we need to change the UUID so that any other prims in the linkset can also be - // deleted). - if (sceneObjectPart.UUID != groupID && groupID != UUID.Zero) - { - _Log.WarnFormat( - "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID", - sceneObjectPart.Name, sceneObjectPart.UUID, sceneObjectPart.GroupPosition, groupID); - - sceneObjectPart.UUID = groupID; - } - - grp = new SceneObjectGroup(sceneObjectPart); - } - else - { - // Black magic to preserve link numbers - // Why is this needed, fix this in AddPart method. - int link = sceneObjectPart.LinkNum; - - grp.AddPart(sceneObjectPart); - - if (link != 0) - sceneObjectPart.LinkNum = link; - } - } - } - } - - if (grp != null) - objects[grp.UUID] = grp; - - // Instead of attempting to LoadItems on every prim, - // most of which probably have no items... get a - // list from DB of all prims which have items and - // LoadItems only on those - List primsWithInventory = new List(); - string qry = "select distinct primID from primitems"; - using (AutoClosingSqlCommand command = _Database.Query(qry)) + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) { - using (SqlDataReader itemReader = command.ExecuteReader()) - { - while (itemReader.Read()) - { - if (!(itemReader["primID"] is DBNull)) - { - UUID primID = new UUID(itemReader["primID"].ToString()); - if (prims.ContainsKey(primID)) - { - primsWithInventory.Add(prims[primID]); - } - } - } - } - } - - LoadItems(primsWithInventory); - - _Log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); + conn.Open(); + Migration m = new Migration(conn, GetType().Assembly, "GridStore"); + m.Update(); + } + } - return new List(objects.Values); - } - - /// - /// Load in the prim's persisted inventory. - /// - /// all prims with inventory on a region - private void LoadItems(List allPrimsWithInventory) + public List Get(string regionName, UUID scopeID) { - - using (AutoClosingSqlCommand command = _Database.Query("SELECT * FROM primitems WHERE PrimID = @PrimID")) + string sql = "select * from ["+m_Realm+"] where regionName like @regionName"; + if (scopeID != UUID.Zero) + sql += " and ScopeID = @scopeID"; + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - foreach (SceneObjectPart objectPart in allPrimsWithInventory) - { - command.Parameters.Clear(); - command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID)); - - List inventory = new List(); - - using (SqlDataReader reader = command.ExecuteReader()) - { - while (reader.Read()) - { - TaskInventoryItem item = BuildItem(reader); - - item.ParentID = objectPart.UUID; // Values in database are - // often wrong - inventory.Add(item); - } - } - - objectPart.Inventory.RestoreInventoryItems(inventory); - } + cmd.Parameters.Add(m_database.CreateParameter("@regionName", regionName)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); + return RunCommand(cmd); } } - /// - /// Stores all object's details apart from inventory - /// - /// - /// - public void StoreObject(SceneObjectGroup obj, UUID regionUUID) + public RegionData Get(int posX, int posY, UUID scopeID) { - _Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); + string sql = "select * from ["+m_Realm+"] where locX = @posX and locY = @posY"; + if (scopeID != UUID.Zero) + sql += " and ScopeID = @scopeID"; - using (SqlConnection conn = _Database.DatabaseConnection()) + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - SqlTransaction transaction = conn.BeginTransaction(); - - try - { - foreach (SceneObjectPart sceneObjectPart in obj.Children.Values) - { - //Update prim - using (SqlCommand sqlCommand = conn.CreateCommand()) - { - sqlCommand.Transaction = transaction; - try - { - StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); - } - catch (SqlException sqlEx) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); - throw; - } - } - - //Update primshapes - using (SqlCommand sqlCommand = conn.CreateCommand()) - { - sqlCommand.Transaction = transaction; - try - { - StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); - } - catch (SqlException sqlEx) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); - throw; - } - } - } - - transaction.Commit(); - } - catch (Exception ex) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message); - try - { - transaction.Rollback(); - } - catch (Exception ex2) - { - //Show error - _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message); - - } - } - } - + cmd.Parameters.Add(m_database.CreateParameter("@posX", posX.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@posY", posY.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); + List ret = RunCommand(cmd); + if (ret.Count == 0) + return null; + + return ret[0]; + } } - /// - /// Stores the prim of the sceneobjectpart. - /// - /// The sceneobjectpart or prim. - /// The SQL command with the transaction. - /// The scenegroup UUID. - /// The region UUID. - private void StoreSceneObjectPrim(SceneObjectPart sceneObjectPart, SqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) + public RegionData Get(UUID regionID, UUID scopeID) { - //Big query to update or insert a new prim. - //Note for SQL Server 2008 this could be simplified - string queryPrims = @" -IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID) - BEGIN - UPDATE prims SET - CreationDate = @CreationDate, Name = @Name, Text = @Text, Description = @Description, SitName = @SitName, - TouchName = @TouchName, ObjectFlags = @ObjectFlags, OwnerMask = @OwnerMask, NextOwnerMask = @NextOwnerMask, GroupMask = @GroupMask, - EveryoneMask = @EveryoneMask, BaseMask = @BaseMask, PositionX = @PositionX, PositionY = @PositionY, PositionZ = @PositionZ, - GroupPositionX = @GroupPositionX, GroupPositionY = @GroupPositionY, GroupPositionZ = @GroupPositionZ, VelocityX = @VelocityX, - VelocityY = @VelocityY, VelocityZ = @VelocityZ, AngularVelocityX = @AngularVelocityX, AngularVelocityY = @AngularVelocityY, - AngularVelocityZ = @AngularVelocityZ, AccelerationX = @AccelerationX, AccelerationY = @AccelerationY, - AccelerationZ = @AccelerationZ, RotationX = @RotationX, RotationY = @RotationY, RotationZ = @RotationZ, RotationW = @RotationW, - SitTargetOffsetX = @SitTargetOffsetX, SitTargetOffsetY = @SitTargetOffsetY, SitTargetOffsetZ = @SitTargetOffsetZ, - SitTargetOrientW = @SitTargetOrientW, SitTargetOrientX = @SitTargetOrientX, SitTargetOrientY = @SitTargetOrientY, - SitTargetOrientZ = @SitTargetOrientZ, RegionUUID = @RegionUUID, CreatorID = @CreatorID, OwnerID = @OwnerID, GroupID = @GroupID, - LastOwnerID = @LastOwnerID, SceneGroupID = @SceneGroupID, PayPrice = @PayPrice, PayButton1 = @PayButton1, PayButton2 = @PayButton2, - PayButton3 = @PayButton3, PayButton4 = @PayButton4, LoopedSound = @LoopedSound, LoopedSoundGain = @LoopedSoundGain, - TextureAnimation = @TextureAnimation, OmegaX = @OmegaX, OmegaY = @OmegaY, OmegaZ = @OmegaZ, CameraEyeOffsetX = @CameraEyeOffsetX, - CameraEyeOffsetY = @CameraEyeOffsetY, CameraEyeOffsetZ = @CameraEyeOffsetZ, CameraAtOffsetX = @CameraAtOffsetX, - CameraAtOffsetY = @CameraAtOffsetY, CameraAtOffsetZ = @CameraAtOffsetZ, ForceMouselook = @ForceMouselook, - ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, - SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, - ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, - LinkNumber = @LinkNumber - WHERE UUID = @UUID - END -ELSE - BEGIN - INSERT INTO - prims ( - UUID, CreationDate, Name, Text, Description, SitName, TouchName, ObjectFlags, OwnerMask, NextOwnerMask, GroupMask, - EveryoneMask, BaseMask, PositionX, PositionY, PositionZ, GroupPositionX, GroupPositionY, GroupPositionZ, VelocityX, - VelocityY, VelocityZ, AngularVelocityX, AngularVelocityY, AngularVelocityZ, AccelerationX, AccelerationY, AccelerationZ, - RotationX, RotationY, RotationZ, RotationW, SitTargetOffsetX, SitTargetOffsetY, SitTargetOffsetZ, SitTargetOrientW, - SitTargetOrientX, SitTargetOrientY, SitTargetOrientZ, RegionUUID, CreatorID, OwnerID, GroupID, LastOwnerID, SceneGroupID, - PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, - OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, - ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, - ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber - ) VALUES ( - @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, - @EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX, - @VelocityY, @VelocityZ, @AngularVelocityX, @AngularVelocityY, @AngularVelocityZ, @AccelerationX, @AccelerationY, @AccelerationZ, - @RotationX, @RotationY, @RotationZ, @RotationW, @SitTargetOffsetX, @SitTargetOffsetY, @SitTargetOffsetZ, @SitTargetOrientW, - @SitTargetOrientX, @SitTargetOrientY, @SitTargetOrientZ, @RegionUUID, @CreatorID, @OwnerID, @GroupID, @LastOwnerID, @SceneGroupID, - @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, - @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, - @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, - @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber - ) - END"; - - //Set commandtext. - sqlCommand.CommandText = queryPrims; - //Add parameters - sqlCommand.Parameters.AddRange(CreatePrimParameters(sceneObjectPart, sceneGroupID, regionUUID)); - - //Execute the query. If it fails then error is trapped in calling function - sqlCommand.ExecuteNonQuery(); - } - - /// - /// Stores the scene object prim shapes. - /// - /// The sceneobjectpart containing prim shape. - /// The SQL command with the transaction. - /// The scenegroup UUID. - /// The region UUID. - private void StoreSceneObjectPrimShapes(SceneObjectPart sceneObjectPart, SqlCommand sqlCommand, UUID sceneGroupID, UUID regionUUID) - { - //Big query to or insert or update primshapes - //Note for SQL Server 2008 this can be simplified - string queryPrimShapes = @" -IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID) - BEGIN - UPDATE primshapes SET - Shape = @Shape, ScaleX = @ScaleX, ScaleY = @ScaleY, ScaleZ = @ScaleZ, PCode = @PCode, PathBegin = @PathBegin, - PathEnd = @PathEnd, PathScaleX = @PathScaleX, PathScaleY = @PathScaleY, PathShearX = @PathShearX, PathShearY = @PathShearY, - PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions, - PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin, - ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow, - Texture = @Texture, ExtraParams = @ExtraParams, State = @State - WHERE UUID = @UUID - END -ELSE - BEGIN - INSERT INTO - primshapes ( - UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, - PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, - ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State - ) VALUES ( - @UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY, - @PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin, - @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State - ) - END"; - - //Set commandtext. - sqlCommand.CommandText = queryPrimShapes; - - //Add parameters - sqlCommand.Parameters.AddRange(CreatePrimShapeParameters(sceneObjectPart, sceneGroupID, regionUUID)); - - //Execute the query. If it fails then error is trapped in calling function - sqlCommand.ExecuteNonQuery(); - - } - - /// - /// Removes a object from the database. - /// Meaning removing it from tables Prims, PrimShapes and PrimItems - /// - /// id of scenegroup - /// regionUUID (is this used anyway - public void RemoveObject(UUID objectID, UUID regionUUID) - { - _Log.InfoFormat("[MSSQL]: Removing obj: {0} from region: {1}", objectID, regionUUID); - - //Remove from prims and primsitem table - string sqlPrims = "DELETE FROM PRIMS WHERE SceneGroupID = @objectID"; - string sqlPrimItems = "DELETE FROM PRIMITEMS WHERE primID in (SELECT UUID FROM PRIMS WHERE SceneGroupID = @objectID)"; - string sqlPrimShapes = "DELETE FROM PRIMSHAPES WHERE uuid in (SELECT UUID FROM PRIMS WHERE SceneGroupID = @objectID)"; - - lock (_Database) + string sql = "select * from ["+m_Realm+"] where uuid = @regionID"; + if (scopeID != UUID.Zero) + sql += " and ScopeID = @scopeID"; + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - //Using the non transaction mode. - using (AutoClosingSqlCommand cmd = _Database.Query(sqlPrimShapes)) - { - cmd.Parameters.Add(_Database.CreateParameter("objectID", objectID)); - cmd.ExecuteNonQuery(); - - cmd.CommandText = sqlPrimItems; - cmd.ExecuteNonQuery(); - - cmd.CommandText = sqlPrims; - cmd.ExecuteNonQuery(); - } + cmd.Parameters.Add(m_database.CreateParameter("@regionID", regionID)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); + List ret = RunCommand(cmd); + if (ret.Count == 0) + return null; + + return ret[0]; } } - /// - /// Store the inventory of a prim. Warning deletes everything first and then adds all again. - /// - /// - /// - public void StorePrimInventory(UUID primID, ICollection items) + public List Get(int startX, int startY, int endX, int endY, UUID scopeID) { - //_Log.InfoFormat("[REGION DB: Persisting Prim Inventory with prim ID {0}", primID); - - //Statement from MySQL section! - // For now, we're just going to crudely remove all the previous inventory items - // no matter whether they have changed or not, and replace them with the current set. + string sql = "select * from ["+m_Realm+"] where locX between @startX and @endX and locY between @startY and @endY"; + if (scopeID != UUID.Zero) + sql += " and ScopeID = @scopeID"; - //Delete everything from PrimID - //TODO add index on PrimID in DB, if not already exist - using (AutoClosingSqlCommand cmd = _Database.Query("DELETE PRIMITEMS WHERE primID = @primID")) + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.Add(_Database.CreateParameter("@primID", primID)); - cmd.ExecuteNonQuery(); - } - - string sql = - @"INSERT INTO primitems ( - itemID,primID,assetID,parentFolderID,invType,assetType,name,description,creationDate,creatorID,ownerID,lastOwnerID,groupID, - nextPermissions,currentPermissions,basePermissions,everyonePermissions,groupPermissions,flags) - VALUES (@itemID,@primID,@assetID,@parentFolderID,@invType,@assetType,@name,@description,@creationDate,@creatorID,@ownerID, - @lastOwnerID,@groupID,@nextPermissions,@currentPermissions,@basePermissions,@everyonePermissions,@groupPermissions,@flags)"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - foreach (TaskInventoryItem taskItem in items) - { - cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem)); - cmd.ExecuteNonQuery(); - - cmd.Parameters.Clear(); - } + cmd.Parameters.Add(m_database.CreateParameter("@startX", startX.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@startY", startY.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@endX", endX.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@endY", endY.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); + return RunCommand(cmd); } } - #endregion - - /// - /// Loads the terrain map. - /// - /// regionID. - /// - public double[,] LoadTerrain(UUID regionID) + public List RunCommand(SqlCommand cmd) { - double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; - terrain.Initialize(); + List retList = new List(); - string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; + SqlDataReader result = cmd.ExecuteReader(); - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + while (result.Read()) { - // MySqlParameter param = new MySqlParameter(); - cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); - - using (SqlDataReader reader = cmd.ExecuteReader()) + RegionData ret = new RegionData(); + ret.Data = new Dictionary(); + + UUID regionID; + UUID.TryParse(result["uuid"].ToString(), out regionID); + ret.RegionID = regionID; + UUID scope; + UUID.TryParse(result["ScopeID"].ToString(), out scope); + ret.ScopeID = scope; + ret.RegionName = result["regionName"].ToString(); + ret.posX = Convert.ToInt32(result["locX"]); + ret.posY = Convert.ToInt32(result["locY"]); + ret.sizeX = Convert.ToInt32(result["sizeX"]); + ret.sizeY = Convert.ToInt32(result["sizeY"]); + + if (m_ColumnNames == null) { - int rev; - if (reader.Read()) - { - MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); - BinaryReader br = new BinaryReader(str); - for (int x = 0; x < (int)Constants.RegionSize; x++) - { - for (int y = 0; y < (int)Constants.RegionSize; y++) - { - terrain[x, y] = br.ReadDouble(); - } - } - rev = (int)reader["Revision"]; - } - else - { - _Log.Info("[REGION DB]: No terrain found for region"); - return null; - } - _Log.Info("[REGION DB]: Loaded terrain revision r" + rev); - } - } - - return terrain; - } + m_ColumnNames = new List(); - /// - /// Stores the terrain map to DB. - /// - /// terrain map data. - /// regionID. - public void StoreTerrain(double[,] terrain, UUID regionID) - { - int revision = Util.UnixTimeSinceEpoch(); - - //Delete old terrain map - string sql = "delete from terrain where RegionUUID=@RegionUUID"; - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); - cmd.ExecuteNonQuery(); - } - - sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); - cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision)); - cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain))); - cmd.ExecuteNonQuery(); - } - - _Log.Info("[REGION DB]: Stored terrain revision r " + revision); - } - - /// - /// Loads all the land objects of a region. - /// - /// The region UUID. - /// - public List LoadLandObjects(UUID regionUUID) - { - List landDataForRegion = new List(); - - string sql = "select * from land where RegionUUID = @RegionUUID"; - - //Retrieve all land data from region - using (AutoClosingSqlCommand cmdLandData = _Database.Query(sql)) - { - cmdLandData.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionUUID)); - - using (SqlDataReader readerLandData = cmdLandData.ExecuteReader()) - { - while (readerLandData.Read()) - { - landDataForRegion.Add(BuildLandData(readerLandData)); - } + DataTable schemaTable = result.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + m_ColumnNames.Add(row["ColumnName"].ToString()); } - } - //Retrieve all accesslist data for all landdata - foreach (LandData landData in landDataForRegion) - { - sql = "select * from landaccesslist where LandUUID = @LandUUID"; - using (AutoClosingSqlCommand cmdAccessList = _Database.Query(sql)) + foreach (string s in m_ColumnNames) { - cmdAccessList.Parameters.Add(_Database.CreateParameter("@LandUUID", landData.GlobalID)); - using (SqlDataReader readerAccessList = cmdAccessList.ExecuteReader()) - { - while (readerAccessList.Read()) - { - landData.ParcelAccessList.Add(BuildLandAccessData(readerAccessList)); - } - } + if (s == "uuid") + continue; + if (s == "ScopeID") + continue; + if (s == "regionName") + continue; + if (s == "locX") + continue; + if (s == "locY") + continue; + + ret.Data[s] = result[s].ToString(); } - } - //Return data - return landDataForRegion; + retList.Add(ret); + } + return retList; } - /// - /// Stores land object with landaccess list. - /// - /// parcel data. - public void StoreLandObject(ILandObject parcel) + public bool Store(RegionData data) { - //As this is only one record in land table I just delete all and then add a new record. - //As the delete landaccess is already in the mysql code - - //Delete old values - RemoveLandObject(parcel.LandData.GlobalID); - - //Insert new values - string sql = @"INSERT INTO [land] -([UUID],[RegionUUID],[LocalLandID],[Bitmap],[Name],[Description],[OwnerUUID],[IsGroupOwned],[Area],[AuctionID],[Category],[ClaimDate],[ClaimPrice],[GroupUUID],[SalePrice],[LandStatus],[LandFlags],[LandingType],[MediaAutoScale],[MediaTextureUUID],[MediaURL],[MusicURL],[PassHours],[PassPrice],[SnapshotUUID],[UserLocationX],[UserLocationY],[UserLocationZ],[UserLookAtX],[UserLookAtY],[UserLookAtZ],[AuthbuyerID],[OtherCleanTime],[Dwell]) -VALUES -(@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID,@OtherCleanTime,@Dwell)"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + if (data.Data.ContainsKey("uuid")) + data.Data.Remove("uuid"); + if (data.Data.ContainsKey("ScopeID")) + data.Data.Remove("ScopeID"); + if (data.Data.ContainsKey("regionName")) + data.Data.Remove("regionName"); + if (data.Data.ContainsKey("posX")) + data.Data.Remove("posX"); + if (data.Data.ContainsKey("posY")) + data.Data.Remove("posY"); + if (data.Data.ContainsKey("sizeX")) + data.Data.Remove("sizeX"); + if (data.Data.ContainsKey("sizeY")) + data.Data.Remove("sizeY"); + if (data.Data.ContainsKey("locX")) + data.Data.Remove("locX"); + if (data.Data.ContainsKey("locY")) + data.Data.Remove("locY"); + + string[] fields = new List(data.Data.Keys).ToArray(); + + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand()) { - cmd.Parameters.AddRange(CreateLandParameters(parcel.LandData, parcel.RegionUUID)); - - cmd.ExecuteNonQuery(); - } - - sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)"; - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.LandData.ParcelAccessList) + string update = "update [" + m_Realm + "] set locX=@posX, locY=@posY, sizeX=@sizeX, sizeY=@sizeY "; + + foreach (string field in fields) { - cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.RegionUUID)); - - cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); - } - } - } - /// - /// Removes a land object from DB. - /// - /// UUID of landobject - public void RemoveLandObject(UUID globalID) - { - using (AutoClosingSqlCommand cmd = _Database.Query("delete from land where UUID=@UUID")) - { - cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); - cmd.ExecuteNonQuery(); - } + update += ", "; + update += "[" + field + "] = @" + field; - using (AutoClosingSqlCommand cmd = _Database.Query("delete from landaccesslist where LandUUID=@UUID")) - { - cmd.Parameters.Add(_Database.CreateParameter("@UUID", globalID)); - cmd.ExecuteNonQuery(); - } - } + cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field])); + } - /// - /// Loads the settings of a region. - /// - /// The region UUID. - /// - public RegionSettings LoadRegionSettings(UUID regionUUID) - { - string sql = "select * from regionsettings where regionUUID = @regionUUID"; - RegionSettings regionSettings; - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) - { - cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionUUID)); - using (SqlDataReader reader = cmd.ExecuteReader()) + update += " where uuid = @regionID"; + + if (data.ScopeID != UUID.Zero) + update += " and ScopeID = @scopeID"; + + cmd.CommandText = update; + cmd.Connection = conn; + cmd.Parameters.Add(m_database.CreateParameter("@regionID", data.RegionID)); + cmd.Parameters.Add(m_database.CreateParameter("@regionName", data.RegionName)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID)); + cmd.Parameters.Add(m_database.CreateParameter("@posX", data.posX)); + cmd.Parameters.Add(m_database.CreateParameter("@posY", data.posY)); + cmd.Parameters.Add(m_database.CreateParameter("@sizeX", data.sizeX)); + cmd.Parameters.Add(m_database.CreateParameter("@sizeY", data.sizeY)); + conn.Open(); + try { - if (reader.Read()) + if (cmd.ExecuteNonQuery() < 1) { - regionSettings = BuildRegionSettings(reader); - regionSettings.OnSave += StoreRegionSettings; + string insert = "insert into [" + m_Realm + "] ([uuid], [ScopeID], [locX], [locY], [sizeX], [sizeY], [regionName], [" + + String.Join("], [", fields) + + "]) values ( @regionID, @scopeID, @posX, @posY, @sizeX, @sizeY, @regionName, @" + String.Join(", @", fields) + ")"; + + cmd.CommandText = insert; - return regionSettings; + try + { + if (cmd.ExecuteNonQuery() < 1) + { + return false; + } + } + catch (Exception ex) + { + m_log.Warn("[MSSQL Grid]: Error inserting into Regions table: " + ex.Message + ", INSERT sql: " + insert); + } } } - } - - //If comes here then there is now region setting for that region - regionSettings = new RegionSettings(); - regionSettings.RegionUUID = regionUUID; - regionSettings.OnSave += StoreRegionSettings; - - //Store new values - StoreNewRegionSettings(regionSettings); - - return regionSettings; - } - - /// - /// Store region settings, need to check if the check is really necesary. If we can make something for creating new region. - /// - /// region settings. - public void StoreRegionSettings(RegionSettings regionSettings) - { - //Little check if regionUUID already exist in DB - string regionUUID; - using (AutoClosingSqlCommand cmd = _Database.Query("SELECT regionUUID FROM regionsettings WHERE regionUUID = @regionUUID")) - { - cmd.Parameters.Add(_Database.CreateParameter("@regionUUID", regionSettings.RegionUUID)); - regionUUID = cmd.ExecuteScalar().ToString(); - } - - if (string.IsNullOrEmpty(regionUUID)) - { - StoreNewRegionSettings(regionSettings); - } - else - { - //This method only updates region settings!!! First call LoadRegionSettings to create new region settings in DB - string sql = - @"UPDATE [regionsettings] SET [block_terraform] = @block_terraform ,[block_fly] = @block_fly ,[allow_damage] = @allow_damage -,[restrict_pushing] = @restrict_pushing ,[allow_land_resell] = @allow_land_resell ,[allow_land_join_divide] = @allow_land_join_divide -,[block_show_in_search] = @block_show_in_search ,[agent_limit] = @agent_limit ,[object_bonus] = @object_bonus ,[maturity] = @maturity -,[disable_scripts] = @disable_scripts ,[disable_collisions] = @disable_collisions ,[disable_physics] = @disable_physics -,[terrain_texture_1] = @terrain_texture_1 ,[terrain_texture_2] = @terrain_texture_2 ,[terrain_texture_3] = @terrain_texture_3 -,[terrain_texture_4] = @terrain_texture_4 ,[elevation_1_nw] = @elevation_1_nw ,[elevation_2_nw] = @elevation_2_nw -,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se -,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit -,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position -,[covenant] = @covenant , [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id - WHERE [regionUUID] = @regionUUID"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + catch (Exception ex) { - cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); - - cmd.ExecuteNonQuery(); + m_log.Warn("[MSSQL Grid]: Error updating Regions table: " + ex.Message + ", UPDATE sql: " + update); } } - } - - public void Shutdown() - { - //Not used?? - } - - #region Private Methods - - /// - /// Serializes the terrain data for storage in DB. - /// - /// terrain data - /// - private static Array serializeTerrain(double[,] val) - { - MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double)); - BinaryWriter bw = new BinaryWriter(str); - - // TODO: COMPATIBILITY - Add byte-order conversions - for (int x = 0; x < (int)Constants.RegionSize; x++) - for (int y = 0; y < (int)Constants.RegionSize; y++) - { - double height = val[x, y]; - if (height == 0.0) - height = double.Epsilon; - bw.Write(height); - } - - return str.ToArray(); + return true; } - /// - /// Stores new regionsettings. - /// - /// The region settings. - private void StoreNewRegionSettings(RegionSettings regionSettings) + public bool SetDataItem(UUID regionID, string item, string value) { - string sql = @"INSERT INTO [regionsettings] - ([regionUUID],[block_terraform],[block_fly],[allow_damage],[restrict_pushing],[allow_land_resell],[allow_land_join_divide], - [block_show_in_search],[agent_limit],[object_bonus],[maturity],[disable_scripts],[disable_collisions],[disable_physics], - [terrain_texture_1],[terrain_texture_2],[terrain_texture_3],[terrain_texture_4],[elevation_1_nw],[elevation_2_nw],[elevation_1_ne], - [elevation_2_ne],[elevation_1_se],[elevation_2_se],[elevation_1_sw],[elevation_2_sw],[water_height],[terrain_raise_limit], - [terrain_lower_limit],[use_estate_sun],[fixed_sun],[sun_position],[covenant],[sunvectorx], [sunvectory], [sunvectorz],[Sandbox], [loaded_creation_datetime], [loaded_creation_id] - ) - VALUES - (@regionUUID,@block_terraform,@block_fly,@allow_damage,@restrict_pushing,@allow_land_resell,@allow_land_join_divide, - @block_show_in_search,@agent_limit,@object_bonus,@maturity,@disable_scripts,@disable_collisions,@disable_physics, - @terrain_texture_1,@terrain_texture_2,@terrain_texture_3,@terrain_texture_4,@elevation_1_nw,@elevation_2_nw,@elevation_1_ne, - @elevation_2_ne,@elevation_1_se,@elevation_2_se,@elevation_1_sw,@elevation_2_sw,@water_height,@terrain_raise_limit, - @terrain_lower_limit,@use_estate_sun,@fixed_sun,@sun_position,@covenant,@sunvectorx,@sunvectory, @sunvectorz, @Sandbox, @loaded_creation_datetime, @loaded_creation_id)"; - - using (AutoClosingSqlCommand cmd = _Database.Query(sql)) + string sql = "update [" + m_Realm + + "] set [" + item + "] = @" + item + " where uuid = @UUID"; + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddRange(CreateRegionSettingParameters(regionSettings)); - cmd.ExecuteNonQuery(); + cmd.Parameters.Add(m_database.CreateParameter("@" + item, value)); + cmd.Parameters.Add(m_database.CreateParameter("@UUID", regionID)); + conn.Open(); + if (cmd.ExecuteNonQuery() > 0) + return true; } + return false; } - #region Private DataRecord conversion methods - - /// - /// Builds the region settings from a datarecod. - /// - /// datarecord with regionsettings. - /// - private static RegionSettings BuildRegionSettings(IDataRecord row) + public bool Delete(UUID regionID) { - //TODO change this is some more generic code so we doesnt have to change it every time a new field is added? - RegionSettings newSettings = new RegionSettings(); - - newSettings.RegionUUID = new UUID((Guid)row["regionUUID"]); - newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); - newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); - newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); - newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); - newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); - newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); - newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); - newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); - newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); - newSettings.Maturity = Convert.ToInt32(row["maturity"]); - newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); - newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); - newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); - newSettings.TerrainTexture1 = new UUID((Guid)row["terrain_texture_1"]); - newSettings.TerrainTexture2 = new UUID((Guid)row["terrain_texture_2"]); - newSettings.TerrainTexture3 = new UUID((Guid)row["terrain_texture_3"]); - newSettings.TerrainTexture4 = new UUID((Guid)row["terrain_texture_4"]); - newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); - newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); - newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); - newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); - newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); - newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); - newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); - newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); - newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); - newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); - newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); - newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); - newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]); - newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); - newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); - newSettings.SunVector = new Vector3( - Convert.ToSingle(row["sunvectorx"]), - Convert.ToSingle(row["sunvectory"]), - Convert.ToSingle(row["sunvectorz"]) - ); - newSettings.Covenant = new UUID((Guid)row["covenant"]); - - newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]); - - if (row["loaded_creation_id"] is DBNull) - newSettings.LoadedCreationID = ""; - else - newSettings.LoadedCreationID = (String)row["loaded_creation_id"]; - return newSettings; - } - - /// - /// Builds the land data from a datarecord. - /// - /// datarecord with land data - /// - private static LandData BuildLandData(IDataRecord row) - { - LandData newData = new LandData(); - - newData.GlobalID = new UUID((Guid)row["UUID"]); - newData.LocalID = Convert.ToInt32(row["LocalLandID"]); - - // Bitmap is a byte[512] - newData.Bitmap = (Byte[])row["Bitmap"]; - - newData.Name = (string)row["Name"]; - newData.Description = (string)row["Description"]; - newData.OwnerID = new UUID((Guid)row["OwnerUUID"]); - newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); - newData.Area = Convert.ToInt32(row["Area"]); - newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented - newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]); - //Enum libsecondlife.Parcel.ParcelCategory - newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); - newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); - newData.GroupID = new UUID((Guid)row["GroupUUID"]); - newData.SalePrice = Convert.ToInt32(row["SalePrice"]); - newData.Status = (ParcelStatus)Convert.ToInt32(row["LandStatus"]); - //Enum. libsecondlife.Parcel.ParcelStatus - newData.Flags = Convert.ToUInt32(row["LandFlags"]); - newData.LandingType = Convert.ToByte(row["LandingType"]); - newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); - newData.MediaID = new UUID((Guid)row["MediaTextureUUID"]); - newData.MediaURL = (string)row["MediaURL"]; - newData.MusicURL = (string)row["MusicURL"]; - newData.PassHours = Convert.ToSingle(row["PassHours"]); - newData.PassPrice = Convert.ToInt32(row["PassPrice"]); - -// UUID authedbuyer; -// UUID snapshotID; -// -// if (UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer)) -// newData.AuthBuyerID = authedbuyer; -// -// if (UUID.TryParse((string)row["SnapshotUUID"], out snapshotID)) -// newData.SnapshotID = snapshotID; - newData.AuthBuyerID = new UUID((Guid) row["AuthBuyerID"]); - newData.SnapshotID = new UUID((Guid)row["SnapshotUUID"]); - - newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); - newData.Dwell = Convert.ToInt32(row["Dwell"]); - - try + string sql = "delete from [" + m_Realm + + "] where uuid = @UUID"; + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) { - newData.UserLocation = - new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), - Convert.ToSingle(row["UserLocationZ"])); - newData.UserLookAt = - new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), - Convert.ToSingle(row["UserLookAtZ"])); + cmd.Parameters.Add(m_database.CreateParameter("@UUID", regionID)); + conn.Open(); + if (cmd.ExecuteNonQuery() > 0) + return true; } - catch (InvalidCastException) - { - newData.UserLocation = Vector3.Zero; - newData.UserLookAt = Vector3.Zero; - _Log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); - } - - newData.ParcelAccessList = new List(); - - return newData; - } - - /// - /// Builds the landaccess data from a data record. - /// - /// datarecord with landaccess data - /// - private static ParcelManager.ParcelAccessEntry BuildLandAccessData(IDataRecord row) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = new UUID((Guid)row["AccessUUID"]); - entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]); - entry.Time = new DateTime(); - return entry; + return false; } - - /// - /// Builds the prim from a datarecord. - /// - /// datarecord - /// - private static SceneObjectPart BuildPrim(IDataRecord primRow) - { - SceneObjectPart prim = new SceneObjectPart(); - - prim.UUID = new UUID((Guid)primRow["UUID"]); - // explicit conversion of integers is required, which sort - // of sucks. No idea if there is a shortcut here or not. - prim.CreationDate = Convert.ToInt32(primRow["CreationDate"]); - prim.Name = (string)primRow["Name"]; - // various text fields - prim.Text = (string)primRow["Text"]; - prim.Color = Color.FromArgb(Convert.ToInt32(primRow["ColorA"]), - Convert.ToInt32(primRow["ColorR"]), - Convert.ToInt32(primRow["ColorG"]), - Convert.ToInt32(primRow["ColorB"])); - prim.Description = (string)primRow["Description"]; - prim.SitName = (string)primRow["SitName"]; - prim.TouchName = (string)primRow["TouchName"]; - // permissions - prim.ObjectFlags = Convert.ToUInt32(primRow["ObjectFlags"]); - prim.CreatorID = new UUID((Guid)primRow["CreatorID"]); - prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); - prim.GroupID = new UUID((Guid)primRow["GroupID"]); - prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); - prim.OwnerMask = Convert.ToUInt32(primRow["OwnerMask"]); - prim.NextOwnerMask = Convert.ToUInt32(primRow["NextOwnerMask"]); - prim.GroupMask = Convert.ToUInt32(primRow["GroupMask"]); - prim.EveryoneMask = Convert.ToUInt32(primRow["EveryoneMask"]); - prim.BaseMask = Convert.ToUInt32(primRow["BaseMask"]); - // vectors - prim.OffsetPosition = new Vector3( - Convert.ToSingle(primRow["PositionX"]), - Convert.ToSingle(primRow["PositionY"]), - Convert.ToSingle(primRow["PositionZ"])); - - prim.GroupPosition = new Vector3( - Convert.ToSingle(primRow["GroupPositionX"]), - Convert.ToSingle(primRow["GroupPositionY"]), - Convert.ToSingle(primRow["GroupPositionZ"])); - - prim.Velocity = new Vector3( - Convert.ToSingle(primRow["VelocityX"]), - Convert.ToSingle(primRow["VelocityY"]), - Convert.ToSingle(primRow["VelocityZ"])); - - prim.AngularVelocity = new Vector3( - Convert.ToSingle(primRow["AngularVelocityX"]), - Convert.ToSingle(primRow["AngularVelocityY"]), - Convert.ToSingle(primRow["AngularVelocityZ"])); - - prim.Acceleration = new Vector3( - Convert.ToSingle(primRow["AccelerationX"]), - Convert.ToSingle(primRow["AccelerationY"]), - Convert.ToSingle(primRow["AccelerationZ"])); - - // quaternions - prim.RotationOffset = new Quaternion( - Convert.ToSingle(primRow["RotationX"]), - Convert.ToSingle(primRow["RotationY"]), - Convert.ToSingle(primRow["RotationZ"]), - Convert.ToSingle(primRow["RotationW"])); - - prim.SitTargetPositionLL = new Vector3( - Convert.ToSingle(primRow["SitTargetOffsetX"]), - Convert.ToSingle(primRow["SitTargetOffsetY"]), - Convert.ToSingle(primRow["SitTargetOffsetZ"])); - - prim.SitTargetOrientationLL = new Quaternion( - Convert.ToSingle(primRow["SitTargetOrientX"]), - Convert.ToSingle(primRow["SitTargetOrientY"]), - Convert.ToSingle(primRow["SitTargetOrientZ"]), - Convert.ToSingle(primRow["SitTargetOrientW"])); - - prim.PayPrice[0] = Convert.ToInt32(primRow["PayPrice"]); - prim.PayPrice[1] = Convert.ToInt32(primRow["PayButton1"]); - prim.PayPrice[2] = Convert.ToInt32(primRow["PayButton2"]); - prim.PayPrice[3] = Convert.ToInt32(primRow["PayButton3"]); - prim.PayPrice[4] = Convert.ToInt32(primRow["PayButton4"]); - - prim.Sound = new UUID((Guid)primRow["LoopedSound"]); - prim.SoundGain = Convert.ToSingle(primRow["LoopedSoundGain"]); - prim.SoundFlags = 1; // If it's persisted at all, it's looped - - if (!(primRow["TextureAnimation"] is DBNull)) - prim.TextureAnimation = (Byte[])primRow["TextureAnimation"]; - if (!(primRow["ParticleSystem"] is DBNull)) - prim.ParticleSystem = (Byte[])primRow["ParticleSystem"]; - - prim.RotationalVelocity = new Vector3( - Convert.ToSingle(primRow["OmegaX"]), - Convert.ToSingle(primRow["OmegaY"]), - Convert.ToSingle(primRow["OmegaZ"])); - - prim.SetCameraEyeOffset(new Vector3( - Convert.ToSingle(primRow["CameraEyeOffsetX"]), - Convert.ToSingle(primRow["CameraEyeOffsetY"]), - Convert.ToSingle(primRow["CameraEyeOffsetZ"]) - )); - - prim.SetCameraAtOffset(new Vector3( - Convert.ToSingle(primRow["CameraAtOffsetX"]), - Convert.ToSingle(primRow["CameraAtOffsetY"]), - Convert.ToSingle(primRow["CameraAtOffsetZ"]) - )); - - if (Convert.ToInt16(primRow["ForceMouselook"]) != 0) - prim.SetForceMouselook(true); - - prim.ScriptAccessPin = Convert.ToInt32(primRow["ScriptAccessPin"]); - - if (Convert.ToInt16(primRow["AllowedDrop"]) != 0) - prim.AllowedDrop = true; - - if (Convert.ToInt16(primRow["DieAtEdge"]) != 0) - prim.DIE_AT_EDGE = true; - - prim.SalePrice = Convert.ToInt32(primRow["SalePrice"]); - prim.ObjectSaleType = Convert.ToByte(primRow["SaleType"]); - - prim.Material = Convert.ToByte(primRow["Material"]); - - if (!(primRow["ClickAction"] is DBNull)) - prim.ClickAction = Convert.ToByte(primRow["ClickAction"]); - - prim.CollisionSound = new UUID((Guid)primRow["CollisionSound"]); - prim.CollisionSoundVolume = Convert.ToSingle(primRow["CollisionSoundVolume"]); - if (Convert.ToInt16(primRow["PassTouches"]) != 0) - prim.PassTouches = true; - prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); - - return prim; - } - - /// - /// Builds the prim shape from a datarecord. - /// - /// The row. - /// - private static PrimitiveBaseShape BuildShape(IDataRecord shapeRow) - { - PrimitiveBaseShape baseShape = new PrimitiveBaseShape(); - - baseShape.Scale = new Vector3( - Convert.ToSingle(shapeRow["ScaleX"]), - Convert.ToSingle(shapeRow["ScaleY"]), - Convert.ToSingle(shapeRow["ScaleZ"])); - - // paths - baseShape.PCode = Convert.ToByte(shapeRow["PCode"]); - baseShape.PathBegin = Convert.ToUInt16(shapeRow["PathBegin"]); - baseShape.PathEnd = Convert.ToUInt16(shapeRow["PathEnd"]); - baseShape.PathScaleX = Convert.ToByte(shapeRow["PathScaleX"]); - baseShape.PathScaleY = Convert.ToByte(shapeRow["PathScaleY"]); - baseShape.PathShearX = Convert.ToByte(shapeRow["PathShearX"]); - baseShape.PathShearY = Convert.ToByte(shapeRow["PathShearY"]); - baseShape.PathSkew = Convert.ToSByte(shapeRow["PathSkew"]); - baseShape.PathCurve = Convert.ToByte(shapeRow["PathCurve"]); - baseShape.PathRadiusOffset = Convert.ToSByte(shapeRow["PathRadiusOffset"]); - baseShape.PathRevolutions = Convert.ToByte(shapeRow["PathRevolutions"]); - baseShape.PathTaperX = Convert.ToSByte(shapeRow["PathTaperX"]); - baseShape.PathTaperY = Convert.ToSByte(shapeRow["PathTaperY"]); - baseShape.PathTwist = Convert.ToSByte(shapeRow["PathTwist"]); - baseShape.PathTwistBegin = Convert.ToSByte(shapeRow["PathTwistBegin"]); - // profile - baseShape.ProfileBegin = Convert.ToUInt16(shapeRow["ProfileBegin"]); - baseShape.ProfileEnd = Convert.ToUInt16(shapeRow["ProfileEnd"]); - baseShape.ProfileCurve = Convert.ToByte(shapeRow["ProfileCurve"]); - baseShape.ProfileHollow = Convert.ToUInt16(shapeRow["ProfileHollow"]); - - byte[] textureEntry = (byte[])shapeRow["Texture"]; - baseShape.TextureEntry = textureEntry; - - baseShape.ExtraParams = (byte[])shapeRow["ExtraParams"]; - - try - { - baseShape.State = Convert.ToByte(shapeRow["State"]); - } - catch (InvalidCastException) - { - } - - return baseShape; - } - - /// - /// Build a prim inventory item from the persisted data. - /// - /// - /// - private static TaskInventoryItem BuildItem(IDataRecord inventoryRow) - { - TaskInventoryItem taskItem = new TaskInventoryItem(); - - taskItem.ItemID = new UUID((Guid)inventoryRow["itemID"]); - taskItem.ParentPartID = new UUID((Guid)inventoryRow["primID"]); - taskItem.AssetID = new UUID((Guid)inventoryRow["assetID"]); - taskItem.ParentID = new UUID((Guid)inventoryRow["parentFolderID"]); - - taskItem.InvType = Convert.ToInt32(inventoryRow["invType"]); - taskItem.Type = Convert.ToInt32(inventoryRow["assetType"]); - - taskItem.Name = (string)inventoryRow["name"]; - taskItem.Description = (string)inventoryRow["description"]; - taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]); - taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]); - taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]); - taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]); - taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]); - - taskItem.NextPermissions = Convert.ToUInt32(inventoryRow["nextPermissions"]); - taskItem.CurrentPermissions = Convert.ToUInt32(inventoryRow["currentPermissions"]); - taskItem.BasePermissions = Convert.ToUInt32(inventoryRow["basePermissions"]); - taskItem.EveryonePermissions = Convert.ToUInt32(inventoryRow["everyonePermissions"]); - taskItem.GroupPermissions = Convert.ToUInt32(inventoryRow["groupPermissions"]); - taskItem.Flags = Convert.ToUInt32(inventoryRow["flags"]); - - return taskItem; - } - - #endregion - - #region Create parameters methods - - /// - /// Creates the prim inventory parameters. - /// - /// item in inventory. - /// - private SqlParameter[] CreatePrimInventoryParameters(TaskInventoryItem taskItem) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("itemID", taskItem.ItemID)); - parameters.Add(_Database.CreateParameter("primID", taskItem.ParentPartID)); - parameters.Add(_Database.CreateParameter("assetID", taskItem.AssetID)); - parameters.Add(_Database.CreateParameter("parentFolderID", taskItem.ParentID)); - parameters.Add(_Database.CreateParameter("invType", taskItem.InvType)); - parameters.Add(_Database.CreateParameter("assetType", taskItem.Type)); - - parameters.Add(_Database.CreateParameter("name", taskItem.Name)); - parameters.Add(_Database.CreateParameter("description", taskItem.Description)); - parameters.Add(_Database.CreateParameter("creationDate", taskItem.CreationDate)); - parameters.Add(_Database.CreateParameter("creatorID", taskItem.CreatorID)); - parameters.Add(_Database.CreateParameter("ownerID", taskItem.OwnerID)); - parameters.Add(_Database.CreateParameter("lastOwnerID", taskItem.LastOwnerID)); - parameters.Add(_Database.CreateParameter("groupID", taskItem.GroupID)); - parameters.Add(_Database.CreateParameter("nextPermissions", taskItem.NextPermissions)); - parameters.Add(_Database.CreateParameter("currentPermissions", taskItem.CurrentPermissions)); - parameters.Add(_Database.CreateParameter("basePermissions", taskItem.BasePermissions)); - parameters.Add(_Database.CreateParameter("everyonePermissions", taskItem.EveryonePermissions)); - parameters.Add(_Database.CreateParameter("groupPermissions", taskItem.GroupPermissions)); - parameters.Add(_Database.CreateParameter("flags", taskItem.Flags)); - - return parameters.ToArray(); - } - - /// - /// Creates the region setting parameters. - /// - /// regionsettings. - /// - private SqlParameter[] CreateRegionSettingParameters(RegionSettings settings) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("regionUUID", settings.RegionUUID)); - parameters.Add(_Database.CreateParameter("block_terraform", settings.BlockTerraform)); - parameters.Add(_Database.CreateParameter("block_fly", settings.BlockFly)); - parameters.Add(_Database.CreateParameter("allow_damage", settings.AllowDamage)); - parameters.Add(_Database.CreateParameter("restrict_pushing", settings.RestrictPushing)); - parameters.Add(_Database.CreateParameter("allow_land_resell", settings.AllowLandResell)); - parameters.Add(_Database.CreateParameter("allow_land_join_divide", settings.AllowLandJoinDivide)); - parameters.Add(_Database.CreateParameter("block_show_in_search", settings.BlockShowInSearch)); - parameters.Add(_Database.CreateParameter("agent_limit", settings.AgentLimit)); - parameters.Add(_Database.CreateParameter("object_bonus", settings.ObjectBonus)); - parameters.Add(_Database.CreateParameter("maturity", settings.Maturity)); - parameters.Add(_Database.CreateParameter("disable_scripts", settings.DisableScripts)); - parameters.Add(_Database.CreateParameter("disable_collisions", settings.DisableCollisions)); - parameters.Add(_Database.CreateParameter("disable_physics", settings.DisablePhysics)); - parameters.Add(_Database.CreateParameter("terrain_texture_1", settings.TerrainTexture1)); - parameters.Add(_Database.CreateParameter("terrain_texture_2", settings.TerrainTexture2)); - parameters.Add(_Database.CreateParameter("terrain_texture_3", settings.TerrainTexture3)); - parameters.Add(_Database.CreateParameter("terrain_texture_4", settings.TerrainTexture4)); - parameters.Add(_Database.CreateParameter("elevation_1_nw", settings.Elevation1NW)); - parameters.Add(_Database.CreateParameter("elevation_2_nw", settings.Elevation2NW)); - parameters.Add(_Database.CreateParameter("elevation_1_ne", settings.Elevation1NE)); - parameters.Add(_Database.CreateParameter("elevation_2_ne", settings.Elevation2NE)); - parameters.Add(_Database.CreateParameter("elevation_1_se", settings.Elevation1SE)); - parameters.Add(_Database.CreateParameter("elevation_2_se", settings.Elevation2SE)); - parameters.Add(_Database.CreateParameter("elevation_1_sw", settings.Elevation1SW)); - parameters.Add(_Database.CreateParameter("elevation_2_sw", settings.Elevation2SW)); - parameters.Add(_Database.CreateParameter("water_height", settings.WaterHeight)); - parameters.Add(_Database.CreateParameter("terrain_raise_limit", settings.TerrainRaiseLimit)); - parameters.Add(_Database.CreateParameter("terrain_lower_limit", settings.TerrainLowerLimit)); - parameters.Add(_Database.CreateParameter("use_estate_sun", settings.UseEstateSun)); - parameters.Add(_Database.CreateParameter("sandbox", settings.Sandbox)); - parameters.Add(_Database.CreateParameter("fixed_sun", settings.FixedSun)); - parameters.Add(_Database.CreateParameter("sun_position", settings.SunPosition)); - parameters.Add(_Database.CreateParameter("sunvectorx", settings.SunVector.X)); - parameters.Add(_Database.CreateParameter("sunvectory", settings.SunVector.Y)); - parameters.Add(_Database.CreateParameter("sunvectorz", settings.SunVector.Z)); - parameters.Add(_Database.CreateParameter("covenant", settings.Covenant)); - parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime)); - parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID)); - - return parameters.ToArray(); - } - - /// - /// Creates the land parameters. - /// - /// land parameters. - /// region UUID. - /// - private SqlParameter[] CreateLandParameters(LandData land, UUID regionUUID) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("UUID", land.GlobalID)); - parameters.Add(_Database.CreateParameter("RegionUUID", regionUUID)); - parameters.Add(_Database.CreateParameter("LocalLandID", land.LocalID)); - - // Bitmap is a byte[512] - parameters.Add(_Database.CreateParameter("Bitmap", land.Bitmap)); - - parameters.Add(_Database.CreateParameter("Name", land.Name)); - parameters.Add(_Database.CreateParameter("Description", land.Description)); - parameters.Add(_Database.CreateParameter("OwnerUUID", land.OwnerID)); - parameters.Add(_Database.CreateParameter("IsGroupOwned", land.IsGroupOwned)); - parameters.Add(_Database.CreateParameter("Area", land.Area)); - parameters.Add(_Database.CreateParameter("AuctionID", land.AuctionID)); //Unemplemented - parameters.Add(_Database.CreateParameter("Category", (int)land.Category)); //Enum libsecondlife.Parcel.ParcelCategory - parameters.Add(_Database.CreateParameter("ClaimDate", land.ClaimDate)); - parameters.Add(_Database.CreateParameter("ClaimPrice", land.ClaimPrice)); - parameters.Add(_Database.CreateParameter("GroupUUID", land.GroupID)); - parameters.Add(_Database.CreateParameter("SalePrice", land.SalePrice)); - parameters.Add(_Database.CreateParameter("LandStatus", (int)land.Status)); //Enum. libsecondlife.Parcel.ParcelStatus - parameters.Add(_Database.CreateParameter("LandFlags", land.Flags)); - parameters.Add(_Database.CreateParameter("LandingType", land.LandingType)); - parameters.Add(_Database.CreateParameter("MediaAutoScale", land.MediaAutoScale)); - parameters.Add(_Database.CreateParameter("MediaTextureUUID", land.MediaID)); - parameters.Add(_Database.CreateParameter("MediaURL", land.MediaURL)); - parameters.Add(_Database.CreateParameter("MusicURL", land.MusicURL)); - parameters.Add(_Database.CreateParameter("PassHours", land.PassHours)); - parameters.Add(_Database.CreateParameter("PassPrice", land.PassPrice)); - parameters.Add(_Database.CreateParameter("SnapshotUUID", land.SnapshotID)); - parameters.Add(_Database.CreateParameter("UserLocationX", land.UserLocation.X)); - parameters.Add(_Database.CreateParameter("UserLocationY", land.UserLocation.Y)); - parameters.Add(_Database.CreateParameter("UserLocationZ", land.UserLocation.Z)); - parameters.Add(_Database.CreateParameter("UserLookAtX", land.UserLookAt.X)); - parameters.Add(_Database.CreateParameter("UserLookAtY", land.UserLookAt.Y)); - parameters.Add(_Database.CreateParameter("UserLookAtZ", land.UserLookAt.Z)); - parameters.Add(_Database.CreateParameter("AuthBuyerID", land.AuthBuyerID)); - parameters.Add(_Database.CreateParameter("OtherCleanTime", land.OtherCleanTime)); - parameters.Add(_Database.CreateParameter("Dwell", land.Dwell)); - - return parameters.ToArray(); - } - - /// - /// Creates the land access parameters. - /// - /// parcel access entry. - /// parcel ID. - /// - private SqlParameter[] CreateLandAccessParameters(ParcelManager.ParcelAccessEntry parcelAccessEntry, UUID parcelID) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("LandUUID", parcelID)); - parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID)); - parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags)); - - return parameters.ToArray(); - } - - /// - /// Creates the prim parameters for storing in DB. - /// - /// Basic data of SceneObjectpart prim. - /// The scenegroup ID. - /// The region ID. - /// - private SqlParameter[] CreatePrimParameters(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) - { - List parameters = new List(); - - parameters.Add(_Database.CreateParameter("UUID", prim.UUID)); - parameters.Add(_Database.CreateParameter("RegionUUID", regionUUID)); - parameters.Add(_Database.CreateParameter("CreationDate", prim.CreationDate)); - parameters.Add(_Database.CreateParameter("Name", prim.Name)); - parameters.Add(_Database.CreateParameter("SceneGroupID", sceneGroupID)); - // the UUID of the root part for this SceneObjectGroup - // various text fields - parameters.Add(_Database.CreateParameter("Text", prim.Text)); - parameters.Add(_Database.CreateParameter("ColorR", prim.Color.R)); - parameters.Add(_Database.CreateParameter("ColorG", prim.Color.G)); - parameters.Add(_Database.CreateParameter("ColorB", prim.Color.B)); - parameters.Add(_Database.CreateParameter("ColorA", prim.Color.A)); - parameters.Add(_Database.CreateParameter("Description", prim.Description)); - parameters.Add(_Database.CreateParameter("SitName", prim.SitName)); - parameters.Add(_Database.CreateParameter("TouchName", prim.TouchName)); - // permissions - parameters.Add(_Database.CreateParameter("ObjectFlags", prim.ObjectFlags)); - parameters.Add(_Database.CreateParameter("CreatorID", prim.CreatorID)); - parameters.Add(_Database.CreateParameter("OwnerID", prim.OwnerID)); - parameters.Add(_Database.CreateParameter("GroupID", prim.GroupID)); - parameters.Add(_Database.CreateParameter("LastOwnerID", prim.LastOwnerID)); - parameters.Add(_Database.CreateParameter("OwnerMask", prim.OwnerMask)); - parameters.Add(_Database.CreateParameter("NextOwnerMask", prim.NextOwnerMask)); - parameters.Add(_Database.CreateParameter("GroupMask", prim.GroupMask)); - parameters.Add(_Database.CreateParameter("EveryoneMask", prim.EveryoneMask)); - parameters.Add(_Database.CreateParameter("BaseMask", prim.BaseMask)); - // vectors - parameters.Add(_Database.CreateParameter("PositionX", prim.OffsetPosition.X)); - parameters.Add(_Database.CreateParameter("PositionY", prim.OffsetPosition.Y)); - parameters.Add(_Database.CreateParameter("PositionZ", prim.OffsetPosition.Z)); - parameters.Add(_Database.CreateParameter("GroupPositionX", prim.GroupPosition.X)); - parameters.Add(_Database.CreateParameter("GroupPositionY", prim.GroupPosition.Y)); - parameters.Add(_Database.CreateParameter("GroupPositionZ", prim.GroupPosition.Z)); - parameters.Add(_Database.CreateParameter("VelocityX", prim.Velocity.X)); - parameters.Add(_Database.CreateParameter("VelocityY", prim.Velocity.Y)); - parameters.Add(_Database.CreateParameter("VelocityZ", prim.Velocity.Z)); - parameters.Add(_Database.CreateParameter("AngularVelocityX", prim.AngularVelocity.X)); - parameters.Add(_Database.CreateParameter("AngularVelocityY", prim.AngularVelocity.Y)); - parameters.Add(_Database.CreateParameter("AngularVelocityZ", prim.AngularVelocity.Z)); - parameters.Add(_Database.CreateParameter("AccelerationX", prim.Acceleration.X)); - parameters.Add(_Database.CreateParameter("AccelerationY", prim.Acceleration.Y)); - parameters.Add(_Database.CreateParameter("AccelerationZ", prim.Acceleration.Z)); - // quaternions - parameters.Add(_Database.CreateParameter("RotationX", prim.RotationOffset.X)); - parameters.Add(_Database.CreateParameter("RotationY", prim.RotationOffset.Y)); - parameters.Add(_Database.CreateParameter("RotationZ", prim.RotationOffset.Z)); - parameters.Add(_Database.CreateParameter("RotationW", prim.RotationOffset.W)); - - // Sit target - Vector3 sitTargetPos = prim.SitTargetPositionLL; - parameters.Add(_Database.CreateParameter("SitTargetOffsetX", sitTargetPos.X)); - parameters.Add(_Database.CreateParameter("SitTargetOffsetY", sitTargetPos.Y)); - parameters.Add(_Database.CreateParameter("SitTargetOffsetZ", sitTargetPos.Z)); - - Quaternion sitTargetOrient = prim.SitTargetOrientationLL; - parameters.Add(_Database.CreateParameter("SitTargetOrientW", sitTargetOrient.W)); - parameters.Add(_Database.CreateParameter("SitTargetOrientX", sitTargetOrient.X)); - parameters.Add(_Database.CreateParameter("SitTargetOrientY", sitTargetOrient.Y)); - parameters.Add(_Database.CreateParameter("SitTargetOrientZ", sitTargetOrient.Z)); - - parameters.Add(_Database.CreateParameter("PayPrice", prim.PayPrice[0])); - parameters.Add(_Database.CreateParameter("PayButton1", prim.PayPrice[1])); - parameters.Add(_Database.CreateParameter("PayButton2", prim.PayPrice[2])); - parameters.Add(_Database.CreateParameter("PayButton3", prim.PayPrice[3])); - parameters.Add(_Database.CreateParameter("PayButton4", prim.PayPrice[4])); - - if ((prim.SoundFlags & 1) != 0) // Looped - { - parameters.Add(_Database.CreateParameter("LoopedSound", prim.Sound)); - parameters.Add(_Database.CreateParameter("LoopedSoundGain", prim.SoundGain)); - } - else - { - parameters.Add(_Database.CreateParameter("LoopedSound", UUID.Zero)); - parameters.Add(_Database.CreateParameter("LoopedSoundGain", 0.0f)); - } - - parameters.Add(_Database.CreateParameter("TextureAnimation", prim.TextureAnimation)); - parameters.Add(_Database.CreateParameter("ParticleSystem", prim.ParticleSystem)); - - parameters.Add(_Database.CreateParameter("OmegaX", prim.RotationalVelocity.X)); - parameters.Add(_Database.CreateParameter("OmegaY", prim.RotationalVelocity.Y)); - parameters.Add(_Database.CreateParameter("OmegaZ", prim.RotationalVelocity.Z)); - - parameters.Add(_Database.CreateParameter("CameraEyeOffsetX", prim.GetCameraEyeOffset().X)); - parameters.Add(_Database.CreateParameter("CameraEyeOffsetY", prim.GetCameraEyeOffset().Y)); - parameters.Add(_Database.CreateParameter("CameraEyeOffsetZ", prim.GetCameraEyeOffset().Z)); - - parameters.Add(_Database.CreateParameter("CameraAtOffsetX", prim.GetCameraAtOffset().X)); - parameters.Add(_Database.CreateParameter("CameraAtOffsetY", prim.GetCameraAtOffset().Y)); - parameters.Add(_Database.CreateParameter("CameraAtOffsetZ", prim.GetCameraAtOffset().Z)); - - if (prim.GetForceMouselook()) - parameters.Add(_Database.CreateParameter("ForceMouselook", 1)); - else - parameters.Add(_Database.CreateParameter("ForceMouselook", 0)); - - parameters.Add(_Database.CreateParameter("ScriptAccessPin", prim.ScriptAccessPin)); - - if (prim.AllowedDrop) - parameters.Add(_Database.CreateParameter("AllowedDrop", 1)); - else - parameters.Add(_Database.CreateParameter("AllowedDrop", 0)); - - if (prim.DIE_AT_EDGE) - parameters.Add(_Database.CreateParameter("DieAtEdge", 1)); - else - parameters.Add(_Database.CreateParameter("DieAtEdge", 0)); - - parameters.Add(_Database.CreateParameter("SalePrice", prim.SalePrice)); - parameters.Add(_Database.CreateParameter("SaleType", prim.ObjectSaleType)); - - byte clickAction = prim.ClickAction; - parameters.Add(_Database.CreateParameter("ClickAction", clickAction)); - - parameters.Add(_Database.CreateParameter("Material", prim.Material)); - - parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound)); - parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume)); - if (prim.PassTouches) - parameters.Add(_Database.CreateParameter("PassTouches", 1)); - else - parameters.Add(_Database.CreateParameter("PassTouches", 0)); - parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); - - return parameters.ToArray(); - } - - /// - /// Creates the primshape parameters for stroing in DB. - /// - /// Basic data of SceneObjectpart prim. - /// The scene group ID. - /// The region UUID. - /// - private SqlParameter[] CreatePrimShapeParameters(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) - { - List parameters = new List(); - - PrimitiveBaseShape s = prim.Shape; - parameters.Add(_Database.CreateParameter("UUID", prim.UUID)); - // shape is an enum - parameters.Add(_Database.CreateParameter("Shape", 0)); - // vectors - parameters.Add(_Database.CreateParameter("ScaleX", s.Scale.X)); - parameters.Add(_Database.CreateParameter("ScaleY", s.Scale.Y)); - parameters.Add(_Database.CreateParameter("ScaleZ", s.Scale.Z)); - // paths - parameters.Add(_Database.CreateParameter("PCode", s.PCode)); - parameters.Add(_Database.CreateParameter("PathBegin", s.PathBegin)); - parameters.Add(_Database.CreateParameter("PathEnd", s.PathEnd)); - parameters.Add(_Database.CreateParameter("PathScaleX", s.PathScaleX)); - parameters.Add(_Database.CreateParameter("PathScaleY", s.PathScaleY)); - parameters.Add(_Database.CreateParameter("PathShearX", s.PathShearX)); - parameters.Add(_Database.CreateParameter("PathShearY", s.PathShearY)); - parameters.Add(_Database.CreateParameter("PathSkew", s.PathSkew)); - parameters.Add(_Database.CreateParameter("PathCurve", s.PathCurve)); - parameters.Add(_Database.CreateParameter("PathRadiusOffset", s.PathRadiusOffset)); - parameters.Add(_Database.CreateParameter("PathRevolutions", s.PathRevolutions)); - parameters.Add(_Database.CreateParameter("PathTaperX", s.PathTaperX)); - parameters.Add(_Database.CreateParameter("PathTaperY", s.PathTaperY)); - parameters.Add(_Database.CreateParameter("PathTwist", s.PathTwist)); - parameters.Add(_Database.CreateParameter("PathTwistBegin", s.PathTwistBegin)); - // profile - parameters.Add(_Database.CreateParameter("ProfileBegin", s.ProfileBegin)); - parameters.Add(_Database.CreateParameter("ProfileEnd", s.ProfileEnd)); - parameters.Add(_Database.CreateParameter("ProfileCurve", s.ProfileCurve)); - parameters.Add(_Database.CreateParameter("ProfileHollow", s.ProfileHollow)); - parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry)); - parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); - parameters.Add(_Database.CreateParameter("State", s.State)); - - return parameters.ToArray(); - } - - #endregion - - #endregion } } diff --git a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs index 38be9f4..7b6e7c8 100644 --- a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs +++ b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs @@ -40,19 +40,21 @@ namespace OpenSim.Data.MSSQL { private string m_Realm; private List m_ColumnNames = null; - private int m_LastExpire = 0; private string m_ConnectionString; + private MSSQLManager m_database; public MSSQLUserAccountData(string connectionString, string realm) { m_Realm = realm; m_ConnectionString = connectionString; + m_database = new MSSQLManager(connectionString); + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) { conn.Open(); Migration m = new Migration(conn, GetType().Assembly, "UserStore"); m.Update(); - } + } } public List Query(UUID principalID, UUID scopeID, string query) @@ -65,16 +67,16 @@ namespace OpenSim.Data.MSSQL UserAccountData ret = new UserAccountData(); ret.Data = new Dictionary(); - string sql = string.Format("select * from '{0}' where UUID = @principalID", m_Realm); + string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm); if (scopeID != UUID.Zero) sql += " and ScopeID = @scopeID"; using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - - cmd.Parameters.AddWithValue("@principalID", principalID); - cmd.Parameters.AddWithValue("@scopeID", scopeID); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); + conn.Open(); using (SqlDataReader result = cmd.ExecuteReader()) { @@ -123,17 +125,16 @@ namespace OpenSim.Data.MSSQL using (SqlCommand cmd = new SqlCommand()) { StringBuilder updateBuilder = new StringBuilder(); - updateBuilder.AppendFormat("update '{0}' set ", m_Realm); + updateBuilder.AppendFormat("update {0} set ", m_Realm); bool first = true; foreach (string field in fields) { if (!first) updateBuilder.Append(", "); - updateBuilder.AppendFormat("'{0}' = @{0}", field); + updateBuilder.AppendFormat("{0} = @{0}", field); first = false; - - cmd.Parameters.AddWithValue("@" + field, data.Data[field]); + cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field])); } updateBuilder.Append(" where UUID = @principalID"); @@ -143,16 +144,16 @@ namespace OpenSim.Data.MSSQL cmd.CommandText = updateBuilder.ToString(); cmd.Connection = conn; - cmd.Parameters.AddWithValue("@principalID", data.PrincipalID); - cmd.Parameters.AddWithValue("@scopeID", data.ScopeID); + cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID)); + cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID)); conn.Open(); if (cmd.ExecuteNonQuery() < 1) { StringBuilder insertBuilder = new StringBuilder(); - insertBuilder.AppendFormat("insert into '{0}' ('UUID', 'ScopeID', '", m_Realm); - insertBuilder.Append(String.Join("', '", fields)); - insertBuilder.Append("') values (@principalID, @scopeID, @"); + insertBuilder.AppendFormat("insert into {0} (UUID, ScopeID, ", m_Realm); + insertBuilder.Append(String.Join(", ", fields)); + insertBuilder.Append(") values ( @principalID, @scopeID, @"); insertBuilder.Append(String.Join(", @", fields)); insertBuilder.Append(")"); @@ -169,12 +170,13 @@ namespace OpenSim.Data.MSSQL public bool SetDataItem(UUID principalID, string item, string value) { - string sql = string.Format("update '{0}' set '{1}' = @{1} where UUID = @UUID", m_Realm, item); + string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item); using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { - cmd.Parameters.AddWithValue("@" + item, value); - cmd.Parameters.AddWithValue("@UUID", principalID); + cmd.Parameters.Add(m_database.CreateParameter("@" + item, value)); + cmd.Parameters.Add(m_database.CreateParameter("@UUID", principalID)); + conn.Open(); if (cmd.ExecuteNonQuery() > 0) diff --git a/OpenSim/Data/MSSQL/Resources/006_GridStore.sql b/OpenSim/Data/MSSQL/Resources/006_GridStore.sql new file mode 100644 index 0000000..42010ce --- /dev/null +++ b/OpenSim/Data/MSSQL/Resources/006_GridStore.sql @@ -0,0 +1,8 @@ +BEGIN TRANSACTION + +ALTER TABLE regions ADD scopeid uniqueidentifier default '00000000-0000-0000-0000-000000000000'; +ALTER TABLE regions ADD DEFAULT ('00000000-0000-0000-0000-000000000000') FOR [owner_uuid]; +ALTER TABLE regions ADD sizeX integer not null default 0; +ALTER TABLE regions ADD sizeY integer not null default 0; + +COMMIT -- cgit v1.1 From 5702c8f910f7e745aaa1bbab2e40b26b361071ad Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 5 Oct 2009 16:31:54 +0100 Subject: Adapt to renamed members in landObject --- OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs index adedcce..e2ae5cb 100644 --- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -575,7 +575,7 @@ ELSE /// public List LoadLandObjects(UUID regionUUID) { - List landDataForRegion = new List(); + List LandDataForRegion = new List(); string sql = "select * from land where RegionUUID = @RegionUUID"; @@ -588,30 +588,30 @@ ELSE { while (readerLandData.Read()) { - landDataForRegion.Add(BuildLandData(readerLandData)); + LandDataForRegion.Add(BuildLandData(readerLandData)); } } } //Retrieve all accesslist data for all landdata - foreach (LandData landData in landDataForRegion) + foreach (LandData LandData in LandDataForRegion) { sql = "select * from landaccesslist where LandUUID = @LandUUID"; using (AutoClosingSqlCommand cmdAccessList = _Database.Query(sql)) { - cmdAccessList.Parameters.Add(_Database.CreateParameter("@LandUUID", landData.GlobalID)); + cmdAccessList.Parameters.Add(_Database.CreateParameter("@LandUUID", LandData.GlobalID)); using (SqlDataReader readerAccessList = cmdAccessList.ExecuteReader()) { while (readerAccessList.Read()) { - landData.ParcelAccessList.Add(BuildLandAccessData(readerAccessList)); + LandData.ParcelAccessList.Add(BuildLandAccessData(readerAccessList)); } } } } //Return data - return landDataForRegion; + return LandDataForRegion; } /// @@ -624,7 +624,7 @@ ELSE //As the delete landaccess is already in the mysql code //Delete old values - RemoveLandObject(parcel.landData.GlobalID); + RemoveLandObject(parcel.LandData.GlobalID); //Insert new values string sql = @"INSERT INTO [land] @@ -634,7 +634,7 @@ VALUES using (AutoClosingSqlCommand cmd = _Database.Query(sql)) { - cmd.Parameters.AddRange(CreateLandParameters(parcel.landData, parcel.regionUUID)); + cmd.Parameters.AddRange(CreateLandParameters(parcel.LandData, parcel.RegionUUID)); cmd.ExecuteNonQuery(); } @@ -643,9 +643,9 @@ VALUES using (AutoClosingSqlCommand cmd = _Database.Query(sql)) { - foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.landData.ParcelAccessList) + foreach (ParcelManager.ParcelAccessEntry parcelAccessEntry in parcel.LandData.ParcelAccessList) { - cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.regionUUID)); + cmd.Parameters.AddRange(CreateLandAccessParameters(parcelAccessEntry, parcel.RegionUUID)); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); -- cgit v1.1 From ad81b453b38b538d5b4c40a326decee2577e024e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Oct 2009 09:02:52 -0700 Subject: GetRegionByPosition: use the cache, Luke. --- .../ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs | 14 ++++++++++++++ .../CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs | 14 ++++++++++++++ 2 files changed, 28 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 3ca4882..1c72488 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs @@ -206,6 +206,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) { + GridRegion region = null; + + // First see if it's a neighbour, even if it isn't on this sim. + // Neighbour data is cached in memory, so this is fast + foreach (RegionCache rcache in m_LocalCache.Values) + { + region = rcache.GetRegionByPosition(x, y); + if (region != null) + { + return region; + } + } + + // Then try on this sim (may be a lookup in DB if this is using MySql). return m_GridService.GetRegionByPosition(scopeID, x, y); } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs index 2b336bb..44e850b 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs @@ -29,10 +29,12 @@ using System; using System.Collections.Generic; using System.Reflection; +using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenMetaverse; using log4net; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid @@ -75,5 +77,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { return new List(m_neighbours.Values); } + + public GridRegion GetRegionByPosition(int x, int y) + { + uint xsnap = (uint)(x / Constants.RegionSize) * Constants.RegionSize; + uint ysnap = (uint)(y / Constants.RegionSize) * Constants.RegionSize; + ulong handle = Utils.UIntsToLong(xsnap, ysnap); + + if (m_neighbours.ContainsKey(handle)) + return m_neighbours[handle]; + + return null; + } } } -- cgit v1.1 From 75b35ddf4aa9fa2e33876bd16651370e67eff9b1 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Oct 2009 09:18:51 -0700 Subject: More error messages to warn when/if things go wrong. --- .../Servers/HttpServer/SynchronousRestFormsRequester.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index 8a490f7..4543fd5 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -28,14 +28,21 @@ using System; using System.IO; using System.Net; +using System.Reflection; using System.Text; using System.Xml; using System.Xml.Serialization; +using log4net; + namespace OpenSim.Framework.Servers.HttpServer { public class SynchronousRestFormsRequester { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + /// /// Perform a synchronous REST request. /// @@ -72,8 +79,9 @@ namespace OpenSim.Framework.Servers.HttpServer requestStream = request.GetRequestStream(); requestStream.Write(buffer.ToArray(), 0, length); } - catch + catch (Exception e) { + m_log.DebugFormat("[FORMS]: exception occured on sending request {0}", e.Message); } finally { @@ -102,7 +110,10 @@ namespace OpenSim.Framework.Servers.HttpServer respstring = reader.ReadToEnd(); } } - catch { } + catch (Exception e) + { + m_log.DebugFormat("[FORMS]: exception occured on receiving reply {0}", e.Message); + } finally { if (respStream != null) @@ -114,6 +125,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (System.InvalidOperationException) { // This is what happens when there is invalid XML + m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request"); } return respstring; } -- cgit v1.1 From 10c4b88ccfb02c84faeeb805226614aeffdebb71 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 5 Oct 2009 18:20:37 +0100 Subject: minor: remove mono compile warning --- OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 0769c90..f5ab1de 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -3476,7 +3476,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override void UnCombine(PhysicsScene pScene) { IntPtr localGround = IntPtr.Zero; - float[] localHeightfield; + //float[] localHeightfield; bool proceed = false; List geomDestroyList = new List(); @@ -3771,16 +3771,13 @@ namespace OpenSim.Region.Physics.OdePlugin sides.Z = 0.5f; ds.DrawBox(ref pos, ref R, ref sides); - - } } } } public void start(int unused) - { - + { ds.SetViewpoint(ref xyz, ref hpr); } #endif -- cgit v1.1 From a2d5da71292ee271617edf28346e6aeb1e153943 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Oct 2009 10:31:09 -0700 Subject: More debug messages if things go wrong. --- OpenSim/Services/GridService/GridService.cs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 991acf2..a2e4771 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -69,18 +69,40 @@ namespace OpenSim.Services.GridService ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY))) { // Region reregistering in other coordinates. Delete the old entry - m_Database.Delete(regionInfos.RegionID); + m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.", + regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY); + + try + { + m_Database.Delete(regionInfos.RegionID); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); + } } // Everything is ok, let's register RegionData rdata = RegionInfo2RegionData(regionInfos); rdata.ScopeID = scopeID; - m_Database.Store(rdata); + try + { + m_Database.Store(rdata); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); + } + + m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}", + regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY); + return true; } public bool DeregisterRegion(UUID regionID) { + m_log.DebugFormat("[GRID SERVICE]: Region {0} deregistered", regionID); return m_Database.Delete(regionID); } -- cgit v1.1 From 2a19187e0195080a0d6894e31f383025af824232 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 5 Oct 2009 18:32:19 +0100 Subject: * minor: tweak asset cache logging levels downwards --- OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs | 12 ++++++------ OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs | 2 +- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 5 +---- OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs index 5a5ad7e..66ca7c2 100644 --- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs @@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Asset { if (maximalSize <= 0 || maximalCount <= 0) { - Log.Info("[ASSET CACHE]: Cenome asset cache is not enabled."); + //Log.Debug("[ASSET CACHE]: Cenome asset cache is not enabled."); m_enabled = false; return; } @@ -194,7 +194,7 @@ namespace OpenSim.Region.CoreModules.Asset CnmSynchronizedCache.Synchronized(new CnmMemoryCache( maximalSize, maximalCount, expirationTime)); m_enabled = true; - Log.InfoFormat( + Log.DebugFormat( "[ASSET CACHE]: Cenome asset cache enabled (MaxSize = {0} bytes, MaxCount = {1}, ExpirationTime = {2})", maximalSize, maximalCount, @@ -263,7 +263,7 @@ namespace OpenSim.Region.CoreModules.Asset if (m_getCount == m_debugEpoch) { - Log.InfoFormat( + Log.DebugFormat( "[ASSET CACHE]: Cached = {0}, Get = {1}, Hits = {2}%, Size = {3} bytes, Avg. A. Size = {4} bytes", m_cachedCount, m_getCount, @@ -333,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Asset return; string name = moduleConfig.GetString("AssetCaching"); - Log.DebugFormat("[XXX] name = {0} (this module's name: {1}", name, Name); + //Log.DebugFormat("[XXX] name = {0} (this module's name: {1}", name, Name); if (name != Name) return; @@ -343,14 +343,14 @@ namespace OpenSim.Region.CoreModules.Asset int maxCount = DefaultMaxCount; TimeSpan expirationTime = DefaultExpirationTime; - IConfig assetConfig = source.Configs[ "AssetCache" ]; + IConfig assetConfig = source.Configs["AssetCache"]; if (assetConfig != null) { // Get optional configurations maxSize = assetConfig.GetLong("MaxSize", DefaultMaxSize); maxCount = assetConfig.GetInt("MaxCount", DefaultMaxCount); expirationTime = - TimeSpan.FromMinutes(assetConfig.GetInt("ExpirationTime", (int) DefaultExpirationTime.TotalMinutes)); + TimeSpan.FromMinutes(assetConfig.GetInt("ExpirationTime", (int)DefaultExpirationTime.TotalMinutes)); // Debugging purposes only m_debugEpoch = assetConfig.GetInt("DebugEpoch", 0); diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs index 2de40d2..0a7e736 100644 --- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.Asset if (moduleConfig != null) { string name = moduleConfig.GetString("AssetCaching"); - m_log.DebugFormat("[XXX] name = {0} (this module's name: {1}", name, Name); + //m_log.DebugFormat("[XXX] name = {0} (this module's name: {1}", name, Name); if (name == Name) { diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index c0bb70c..b81ab41 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -636,11 +636,8 @@ namespace Flotsam.RegionModules.AssetCache m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache clearfile - Remove all assets cached on disk"); } - - } #endregion - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs index 8d8e0fe..4869f5d 100644 --- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Asset if (moduleConfig != null) { string name = moduleConfig.GetString("AssetCaching"); - m_log.DebugFormat("[ASSET CACHE] name = {0} (this module's name: {1}). Sync? ", name, Name, m_Cache.IsSynchronized); + //m_log.DebugFormat("[ASSET CACHE] name = {0} (this module's name: {1}). Sync? ", name, Name, m_Cache.IsSynchronized); if (name == Name) { -- cgit v1.1 From 05c1ec7fafe581e368d57138b2d1df7e590c2dd5 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Oct 2009 11:01:45 -0700 Subject: Changed the lock object, to see if this helps at all. Also switched the order of lock and try/catch in RemoveImageFromQueue. --- .../Region/ClientStack/LindenUDP/LLImageManager.cs | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index 2120d33..cc290ed 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs @@ -88,7 +88,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP J2KImage imgrequest; // Do a linear search for this texture download - lock (m_priorityQueue) + lock (m_syncRoot) m_priorityQueue.Find(delegate(J2KImage img) { return img.TextureID == newRequest.RequestedAssetID; }, out imgrequest); if (imgrequest != null) @@ -99,7 +99,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP try { - lock (m_priorityQueue) + lock (m_syncRoot) m_priorityQueue.Delete(imgrequest.PriorityQueueHandle); } catch (Exception) { } @@ -211,7 +211,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { J2KImage image = null; - lock (m_priorityQueue) + lock (m_syncRoot) { if (m_priorityQueue.Count > 0) @@ -230,23 +230,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP { image.PriorityQueueHandle = null; - lock (m_priorityQueue) - m_priorityQueue.Add(ref image.PriorityQueueHandle, image); + lock (m_syncRoot) + try + { + m_priorityQueue.Add(ref image.PriorityQueueHandle, image); + } + catch (Exception) { } } void RemoveImageFromQueue(J2KImage image) { - try - { - lock (m_priorityQueue) + lock (m_syncRoot) + try + { m_priorityQueue.Delete(image.PriorityQueueHandle); - } - catch (Exception) { } + } + catch (Exception) { } } void UpdateImageInQueue(J2KImage image) { - lock (m_priorityQueue) + lock (m_syncRoot) { try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); } catch (Exception) -- cgit v1.1 From 5f18a088a83c9997e1fe026241de2c0db1a961b8 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Oct 2009 11:14:46 -0700 Subject: More error catching/outputting. --- OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index e22328d..b425d90 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -137,11 +137,21 @@ namespace OpenSim.Server.Handlers.Grid } Dictionary rinfoData = new Dictionary(); - foreach (KeyValuePair kvp in request) - rinfoData[kvp.Key] = kvp.Value; - GridRegion rinfo = new GridRegion(rinfoData); + GridRegion rinfo = null; + try + { + foreach (KeyValuePair kvp in request) + rinfoData[kvp.Key] = kvp.Value; + rinfo = new GridRegion(rinfoData); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID HANDLER]: exception unpacking region data: {0}", e); + } - bool result = m_GridService.RegisterRegion(scopeID, rinfo); + bool result = false; + if (rinfo != null) + m_GridService.RegisterRegion(scopeID, rinfo); if (result) return SuccessResult(); -- cgit v1.1 From 05b80185b9f74979eeab0d60ae4d7de56593264c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Oct 2009 11:49:21 -0700 Subject: More debug to try to diagnose a problem with region registration. --- OpenSim/Server/Base/ServerUtils.cs | 2 +- OpenSim/Services/Connectors/Grid/GridServiceConnector.cs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 0964caa..9d9735e 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -260,7 +260,7 @@ namespace OpenSim.Server.Base public static Dictionary ParseXmlResponse(string data) { - //m_log.DebugFormat("[XXX]: received xml string: {0}", data); + m_log.DebugFormat("[XXX]: received xml string: {0}", data); Dictionary ret = new Dictionary(); diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs index ba46b0d..acdf558 100644 --- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs @@ -109,8 +109,13 @@ namespace OpenSim.Services.Connectors { Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - if ((replyData["Result"] != null) && (replyData["Result"].ToString().ToLower() == "success")) + if (replyData.ContainsKey("Result")&& (replyData["Result"].ToString().ToLower() == "success")) return true; + else if (!replyData.ContainsKey("Result")) + m_log.DebugFormat("[GRID CONNECTOR]: reply data does not contain result field"); + else + m_log.DebugFormat("[GRID CONNECTOR]: unexpected result {0}", replyData["Result"].ToString()); + } else m_log.DebugFormat("[GRID CONNECTOR]: RegisterRegion received null reply"); -- cgit v1.1 From 9bd1353875d40806cbe76b8afca17ed5a93e9efd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Oct 2009 12:13:38 -0700 Subject: Fixed bug introduced in one of the last commits. --- OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index b425d90..08edcbf 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -151,7 +151,7 @@ namespace OpenSim.Server.Handlers.Grid bool result = false; if (rinfo != null) - m_GridService.RegisterRegion(scopeID, rinfo); + result = m_GridService.RegisterRegion(scopeID, rinfo); if (result) return SuccessResult(); -- cgit v1.1 From 282b7520355749466b7142a8273e7eaa3e92ebc1 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Oct 2009 13:14:14 -0700 Subject: Minor change. --- OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index 08edcbf..17a31bc 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -113,7 +113,7 @@ namespace OpenSim.Server.Handlers.Grid byte[] Register(Dictionary request) { UUID scopeID = UUID.Zero; - if (request["SCOPEID"] != null) + if (request.ContainsKey("SCOPEID")) UUID.TryParse(request["SCOPEID"], out scopeID); else m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to register region"); -- cgit v1.1 From 544675d0f0969ce19ca41d3e70b0b0d5c853210a Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Mon, 5 Oct 2009 11:59:33 -0700 Subject: Ensure the specified imSessionID exists in the DroppedSession collection before attempting to access it. --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 631d801..00fe5df 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -425,7 +425,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) { - if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) + if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) { // Don't deliver messages to people who have dropped this session if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); -- cgit v1.1 From d4a6d9191a3ba4f19773213617843ddbb489c90c Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Mon, 5 Oct 2009 12:09:45 -0700 Subject: Make sure that keys exist in arrays before trying to access them. --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 2e89a24..b209199 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -148,9 +148,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; foreach (UUID key in CurrentKeys) { - if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) + if (m_clientRequestIDInfo.ContainsKey(key)) { - m_clientRequestIDInfo.Remove(key); + if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) + { + m_clientRequestIDInfo.Remove(key); + } } } } @@ -476,7 +479,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (string key in binBucketOSD.Keys) { - m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + if (binBucketOSD.ContainsKey(key)) + { + m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + } } } -- cgit v1.1 From 2753f4d62c79b45f5ad1b3e275d7a9c628d34687 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Oct 2009 16:06:21 -0700 Subject: * GridServerPostHandler.cs: Try/catch in Handle * BaseOpenSimServer.cs: Added thread pool numbers in show threads --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 8 +++- .../Server/Handlers/Grid/GridServerPostHandler.cs | 55 ++++++++++++---------- 2 files changed, 38 insertions(+), 25 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 632b551..56155dd 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -238,7 +238,7 @@ namespace OpenSim.Framework.Servers List threads = ThreadTracker.GetThreads(); if (threads == null) { - sb.Append("Thread tracking is only enabled in DEBUG mode."); + sb.Append("OpenSim thread tracking is only enabled in DEBUG mode."); } else { @@ -264,6 +264,12 @@ namespace OpenSim.Framework.Servers } } } + int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; + ThreadPool.GetAvailableThreads(out workers, out ports); + ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts); + + sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine); + sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine); return sb.ToString(); } diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index 17a31bc..433ed0b 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -67,43 +67,50 @@ namespace OpenSim.Server.Handlers.Grid //m_log.DebugFormat("[XXX]: query String: {0}", body); - Dictionary request = - ServerUtils.ParseQueryString(body); + try + { + Dictionary request = + ServerUtils.ParseQueryString(body); - if (!request.ContainsKey("METHOD")) - return FailureResult(); + if (!request.ContainsKey("METHOD")) + return FailureResult(); - string method = request["METHOD"]; + string method = request["METHOD"]; - switch (method) - { - case "register": - return Register(request); + switch (method) + { + case "register": + return Register(request); - case "deregister": - return Deregister(request); + case "deregister": + return Deregister(request); - case "get_neighbours": - return GetNeighbours(request); + case "get_neighbours": + return GetNeighbours(request); - case "get_region_by_uuid": - return GetRegionByUUID(request); + case "get_region_by_uuid": + return GetRegionByUUID(request); - case "get_region_by_position": - return GetRegionByPosition(request); + case "get_region_by_position": + return GetRegionByPosition(request); - case "get_region_by_name": - return GetRegionByName(request); + case "get_region_by_name": + return GetRegionByName(request); - case "get_regions_by_name": - return GetRegionsByName(request); + case "get_regions_by_name": + return GetRegionsByName(request); - case "get_region_range": - return GetRegionRange(request); + case "get_region_range": + return GetRegionRange(request); + } + m_log.DebugFormat("[GRID HANDLER]: unknown method {0} request {1}", method.Length, method); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID HANDLER]: Exception {0}", e); } - m_log.DebugFormat("[GRID HANDLER]: unknown method {0} request {1}", method.Length, method); return FailureResult(); } -- cgit v1.1 From 672036937671a69426a12936c69efcb54d029e86 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Mon, 5 Oct 2009 16:39:40 -0700 Subject: Added CloseDBConnection() to replace the old CloseReaderCommand(). This will close the MySQLConnection attached to a MySQLCommand. I'm not sure if this accounts for every time a database connection needs to be closed, but it matches up 1:1 with the places where the database connection was previously being closed --- OpenSim/Data/MySQL/MySQLAuthenticationData.cs | 8 ++++++-- OpenSim/Data/MySQL/MySQLFramework.cs | 14 +++++++------- OpenSim/Data/MySQL/MySQLRegionData.cs | 2 ++ OpenSim/Data/MySQL/MySQLUserAccountData.cs | 8 ++++++-- 4 files changed, 21 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index e96a123..a41f9f8 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -82,12 +82,16 @@ namespace OpenSim.Data.MySQL ret.Data[s] = result[s].ToString(); } + CloseDBConnection(cmd); return ret; } + else + { + CloseDBConnection(cmd); + return null; + } } } - - return null; } public bool Store(AuthenticationData data) diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs index c756c9c..f37e9bc 100644 --- a/OpenSim/Data/MySQL/MySQLFramework.cs +++ b/OpenSim/Data/MySQL/MySQLFramework.cs @@ -47,7 +47,6 @@ namespace OpenSim.Data.MySQL protected MySqlFramework(string connectionString) { m_Connection = new MySqlConnection(connectionString); - m_Connection.Open(); } @@ -82,8 +81,7 @@ namespace OpenSim.Data.MySQL errorSeen = true; m_Connection.Close(); - MySqlConnection newConnection = (MySqlConnection) - ((ICloneable)m_Connection).Clone(); + MySqlConnection newConnection = (MySqlConnection)((ICloneable)m_Connection).Clone(); m_Connection.Dispose(); m_Connection = newConnection; m_Connection.Open(); @@ -104,14 +102,16 @@ namespace OpenSim.Data.MySQL protected IDataReader ExecuteReader(MySqlCommand cmd) { - MySqlConnection newConnection = (MySqlConnection) - ((ICloneable)m_Connection).Clone(); - + MySqlConnection newConnection = (MySqlConnection)((ICloneable)m_Connection).Clone(); newConnection.Open(); cmd.Connection = newConnection; - return cmd.ExecuteReader(); } + + protected void CloseDBConnection(MySqlCommand cmd) + { + cmd.Connection.Dispose(); + } } } diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index 04b24b6..3fe27d5 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -172,6 +172,8 @@ namespace OpenSim.Data.MySQL retList.Add(ret); } + + CloseDBConnection(cmd); } return retList; diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs index c713a11..38a6f55 100644 --- a/OpenSim/Data/MySQL/MySQLUserAccountData.cs +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs @@ -97,12 +97,16 @@ namespace OpenSim.Data.MySQL ret.Data[s] = result[s].ToString(); } + CloseDBConnection(cmd); return ret; } + else + { + CloseDBConnection(cmd); + return null; + } } } - - return null; } public bool Store(UserAccountData data) -- cgit v1.1